Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1797652: Fix crash on Edit of applications
- Loading branch information
1 parent
63830a9
commit e19f218
Showing
12 changed files
with
95 additions
and
37 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
frontend/__tests__/components/utils/truncate-utils.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
truncateMiddle, | ||
shouldTruncate, | ||
TruncateOptions, | ||
} from '../../../public/components/utils/truncate-middle'; | ||
|
||
const testTruncateText = 'ThisTextShouldBeTruncatedByDefault'; | ||
|
||
describe('truncateMiddle: ', () => { | ||
it('should truncate to 20 characters, in the middle, with ellipse by default', () => { | ||
expect(shouldTruncate(testTruncateText)).toBe(true); | ||
const truncateResult = truncateMiddle(testTruncateText); | ||
const splits = truncateResult.split('\u2026'); | ||
expect(truncateResult.length).toBe(20); | ||
expect(splits[0].length).toBeGreaterThan(1); | ||
expect(splits[1].length).toBeGreaterThan(1); | ||
}); | ||
|
||
it('should honor setting the length', () => { | ||
const options: TruncateOptions = { length: 50 }; | ||
expect(shouldTruncate(testTruncateText, options)).toBe(false); | ||
const truncateResult = truncateMiddle(testTruncateText, options); | ||
const splits = truncateResult.split('\u2026'); | ||
expect(truncateResult.length).toBe(testTruncateText.length); | ||
expect(splits.length).toBe(1); | ||
}); | ||
|
||
it('should honor truncating at the end', () => { | ||
const options: TruncateOptions = { truncateEnd: true }; | ||
expect(shouldTruncate(testTruncateText, options)).toBe(true); | ||
const truncateResult = truncateMiddle(testTruncateText, options); | ||
const splits = truncateResult.split('\u2026'); | ||
expect(truncateResult.length).toBe(20); | ||
expect(splits[0].length).toBe(19); | ||
expect(splits[1].length).toBe(0); | ||
}); | ||
|
||
it('should honor the omission text', () => { | ||
const options: TruncateOptions = { omission: 'zzz' }; | ||
expect(shouldTruncate(testTruncateText, options)).toBe(true); | ||
const truncateResult = truncateMiddle(testTruncateText, options); | ||
const splits = truncateResult.split('zzz'); | ||
expect(truncateResult.length).toBe(20); | ||
expect(splits.length).toBe(2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,49 @@ | ||
const DEFAULT_OPTIONS = { | ||
export type TruncateOptions = { | ||
length?: number; // Length to truncate text to | ||
truncateEnd?: boolean; // Flag to alternatively truncate at the end | ||
omission?: string; // Truncation text used to denote the truncation (ellipsis) | ||
minTruncateChars?: number; // Minimum number of characters to truncate | ||
}; | ||
|
||
const DEFAULT_OPTIONS: TruncateOptions = { | ||
length: 20, | ||
truncateEnd: false, | ||
omission: '\u2026', // ellipsis character | ||
minTruncateChars: 3, | ||
}; | ||
|
||
// Truncates a string down to `maxLength` characters by replacing the middle | ||
// the provided omission option (ellipsis character by default); | ||
export const truncateMiddle = (text, options = {}): string => { | ||
const { length, omission } = Object.assign({}, DEFAULT_OPTIONS, options); | ||
// Truncates a string down to `maxLength` characters when the length | ||
// is greater than the `maxLength` + `minTruncateChars` values. | ||
// By default the middle is truncated, set the options.truncateEnd to true to truncate at the end. | ||
// Truncated text is replaced with the provided omission option (ellipsis character by default); | ||
export const truncateMiddle = (text: string, options: TruncateOptions = {}): string => { | ||
const { length, truncateEnd, omission, minTruncateChars } = { ...DEFAULT_OPTIONS, ...options }; | ||
if (!text) { | ||
return text; | ||
} | ||
|
||
if (text.length <= length) { | ||
// Do not truncate less than the minimum truncate characters | ||
if (text.length <= length + minTruncateChars) { | ||
return text; | ||
} | ||
|
||
if (length <= omission.length) { | ||
return omission; | ||
} | ||
|
||
if (truncateEnd) { | ||
return `${text.substr(0, length - 1)}${omission}`; | ||
} | ||
|
||
const startLength = Math.ceil((length - omission.length) / 2); | ||
const endLength = length - startLength - omission.length; | ||
const startFragment = text.substr(0, startLength); | ||
const endFragment = text.substr(text.length - endLength); | ||
return `${startFragment}${omission}${endFragment}`; | ||
}; | ||
|
||
export const shouldTruncate = (text, options: TruncateOptions = {}): boolean => { | ||
const { length, minTruncateChars } = { ...DEFAULT_OPTIONS, ...options }; | ||
|
||
return text.length > length + minTruncateChars; | ||
}; |