Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0ebcede
commit
yashgoyal0110 Mar 11, 2025
ca4de6e
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 12, 2025
95c2051
Update pnpm-lock.yaml
yashgoyal0110 Mar 12, 2025
98e8cd4
Update vite.config.ts
yashgoyal0110 Mar 12, 2025
d126560
Update package.json
yashgoyal0110 Mar 12, 2025
7117a69
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 14, 2025
3ee3a64
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 15, 2025
c0dd7d4
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 15, 2025
1fe7197
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 15, 2025
1916577
Merge branch 'OWASP:main' into main
yashgoyal0110 Mar 15, 2025
269ff95
truncate text component
yashgoyal0110 Mar 15, 2025
2aeffce
commit
yashgoyal0110 Mar 15, 2025
563902a
Merge branch 'main' into feat/TruncatedText-component
kasya Mar 16, 2025
e4ad50d
Merge branch 'main' into feat/TruncatedText-component
yashgoyal0110 Mar 16, 2025
8db1ffa
commit
yashgoyal0110 Mar 16, 2025
8041c12
commit
yashgoyal0110 Mar 16, 2025
ccb61a2
commit
yashgoyal0110 Mar 16, 2025
170f5b4
commit
yashgoyal0110 Mar 16, 2025
8cebc03
commit
yashgoyal0110 Mar 16, 2025
698c9a8
commit
yashgoyal0110 Mar 16, 2025
19ca19c
commit
yashgoyal0110 Mar 16, 2025
b1d9fad
commit
yashgoyal0110 Mar 16, 2025
4d36fd9
commit
yashgoyal0110 Mar 16, 2025
c56666b
Merge branch 'OWASP:main' into feat/TruncatedText-component
yashgoyal0110 Mar 21, 2025
7fafc90
fixed e2e and improved truncate component
yashgoyal0110 Mar 21, 2025
1a57db6
fixed pre-commit
yashgoyal0110 Mar 21, 2025
cbae4b9
Merge branch 'main' into feat/TruncatedText-component
arkid15r Mar 21, 2025
e5c1427
Merge branch 'main' into feat/TruncatedText-component
arkid15r Mar 22, 2025
0e409b8
comit
yashgoyal0110 Mar 23, 2025
ae8344c
comit
yashgoyal0110 Mar 23, 2025
38808c6
Merge branch 'OWASP:main' into feat/TruncatedText-component
yashgoyal0110 Mar 23, 2025
79bb085
commit
yashgoyal0110 Mar 24, 2025
e431133
Merge branch 'main' into feat/TruncatedText-component
arkid15r Mar 24, 2025
e8ebf83
fixed unit tests
yashgoyal0110 Mar 24, 2025
464d980
fixed unit test
yashgoyal0110 Mar 24, 2025
39bf7bb
commit
yashgoyal0110 Mar 24, 2025
da5da20
Update code
arkid15r Mar 24, 2025
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
11 changes: 11 additions & 0 deletions frontend/__tests__/e2e/pages/Home.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,15 @@ test.describe('Home Page', () => {
await expect(page.getByText('Feb 27 — 28, 2025')).toBeVisible()
await page.getByRole('button', { name: 'Event 1' }).click()
})

test('should have truncated text with overflow for all relevant elements', async ({ page }) => {
const truncatedElements = await page.locator('span.truncate').all()
expect(truncatedElements.length).toBeGreaterThan(0)

for (const element of truncatedElements) {
await expect(element).toHaveCSS('overflow', 'hidden')
await expect(element).toHaveCSS('text-overflow', 'ellipsis')
await expect(element).toHaveCSS('white-space', 'nowrap')
}
})
})
30 changes: 30 additions & 0 deletions frontend/__tests__/unit/components/TruncatedText.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { render, screen } from 'wrappers/testUtil'
import { TruncatedText } from 'components/TruncatedText'

describe('TruncatedText Component', () => {
const longText = 'This is very long text that should be truncated for display.'

test('renders full text when it fits within the container', () => {
render(<TruncatedText text="Short text" className="w-auto" />)
const textElement = screen.getByText('Short text')
expect(textElement).toBeInTheDocument()
expect(textElement).toHaveAttribute('title', 'Short text')
})

test('truncates text when it exceeds container width', () => {
render(
<div style={{ width: '100px' }}>
<TruncatedText text={longText} />
</div>
)
const textElement = screen.getByText(longText)
expect(textElement).toHaveClass('truncate')
expect(textElement).toHaveClass('text-ellipsis')
})

test('title attribute is always present', () => {
render(<TruncatedText text={longText} />)
const textElement = screen.getByText(longText)
expect(textElement).toHaveAttribute('title', longText)
})
})
9 changes: 7 additions & 2 deletions frontend/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ if (!global.structuredClone) {
global.structuredClone = (val) => JSON.parse(JSON.stringify(val))
}

// mock runAnimationFrameCallbacks function for testing
beforeAll(() => {
if (typeof window !== 'undefined') {
jest.spyOn(window, 'requestAnimationFrame').mockImplementation((cb) => {
Expand All @@ -22,10 +21,16 @@ beforeAll(() => {

Object.defineProperty(window, 'runAnimationFrameCallbacks', {
value: () => {},
writable: true,
configurable: true,
writable: true,
})
}

global.ResizeObserver = class {
disconnect() {}
observe() {}
unobserve() {}
}
})

beforeEach(() => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/ItemCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { JSX } from 'react'
import { ProjectIssuesType, ProjectReleaseType } from 'types/project'
import { PullRequestsType } from 'types/user'
import SecondaryCard from './SecondaryCard'
import { TruncatedText } from './TruncatedText'

const ItemCardList = ({
title,
Expand Down Expand Up @@ -44,7 +45,7 @@ const ItemCardList = ({
href={item?.url}
target="_blank"
>
{item.title || item.name}
<TruncatedText text={item.title || item.name} />
</a>
</h3>
</div>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/RepositoriesCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type React from 'react'
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { RepositoriesCardProps } from 'types/project'
import { TruncatedText } from './TruncatedText'

const RepositoriesCard: React.FC<RepositoriesCardProps> = ({ repositories }) => {
const [showAllRepositories, setShowAllRepositories] = useState(false)
Expand Down Expand Up @@ -59,7 +60,7 @@ const RepositoryItem = ({ details }) => {
onClick={handleClick}
className="text-start font-semibold text-blue-500 hover:underline dark:text-blue-400"
>
{details?.name}
<TruncatedText text={details?.name} />
</button>

<div className="space-y-2 text-sm">
Expand Down
37 changes: 37 additions & 0 deletions frontend/src/components/TruncatedText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useRef, useEffect, useCallback } from 'react'

export const TruncatedText = ({ text, className = '' }: { text: string; className?: string }) => {
const textRef = useRef<HTMLSpanElement>(null)

const checkTruncation = useCallback(() => {
const element = textRef.current
if (element) {
element.title = text
}
}, [text])

useEffect(() => {
checkTruncation()

const observer = new ResizeObserver(() => checkTruncation())
if (textRef.current) {
observer.observe(textRef.current)
}

window.addEventListener('resize', checkTruncation)

return () => {
observer.disconnect()
window.removeEventListener('resize', checkTruncation)
}
}, [text, checkTruncation])

return (
<span
ref={textRef}
className={`block overflow-hidden truncate text-ellipsis whitespace-nowrap ${className}`}
>
{text}
</span>
)
}
33 changes: 17 additions & 16 deletions frontend/src/pages/Home.tsx

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue description contains Apply the component for all existing cases to make sure the universal look and it seems the current code contains home page only improvements.

@yashgoyal0110 yashgoyal0110 Mar 22, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all existing cases also includes project, issue and chapter card titles?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We want a consistent look, not just a main page fix.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Modal from 'components/Modal'
import MultiSearchBar from 'components/MultiSearch'
import SecondaryCard from 'components/SecondaryCard'
import TopContributors from 'components/ToggleContributors'
import { TruncatedText } from 'components/TruncatedText'
import { toaster } from 'components/ui/toaster'

export default function Home() {
Expand Down Expand Up @@ -135,16 +136,16 @@ export default function Home() {
/>
</div>
</div>
<SecondaryCard title="Upcoming Events">
<SecondaryCard title="Upcoming Events" className="overflow-hidden">
<div className="grid gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
{data.upcomingEvents.map((event: EventType, index: number) => (
<div key={`card-${event.name}`}>
<div key={`card-${event.name}`} className="overflow-hidden">
<div className="rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
<button
className="mb-2 w-full text-left text-lg font-semibold text-blue-500 hover:underline"
onClick={() => setModalOpenIndex(index)}
>
<h3 className="truncate text-wrap md:text-nowrap">{event.name}</h3>
<TruncatedText text={event.name} />
</button>
<div className="flex flex-col flex-wrap items-start text-sm text-gray-600 dark:text-gray-300 md:flex-row">
<div className="mr-2 flex items-center">
Expand Down Expand Up @@ -173,13 +174,13 @@ export default function Home() {
</div>
</SecondaryCard>
<div className="grid gap-4 md:grid-cols-2">
<SecondaryCard title="New Chapters">
<SecondaryCard title="New Chapters" className="overflow-hidden">
<div className="space-y-4">
{data.recentChapters.map((chapter) => (
<div key={chapter.key} className="rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
<h3 className="mb-2 text-lg font-semibold">
<a href={`/chapters/${chapter.key}`} className="hover:underline">
{chapter.name}
<TruncatedText text={chapter.name} />
</a>
</h3>
<div className="flex flex-wrap items-center text-sm text-gray-600 dark:text-gray-300">
Expand All @@ -202,15 +203,15 @@ export default function Home() {
))}
</div>
</SecondaryCard>
<SecondaryCard title="New Projects">
<SecondaryCard title="New Projects" className="overflow-hidden">
<div className="space-y-4">
{data.recentProjects.map((project) => (
<div key={project.key} className="rounded-lg bg-gray-200 p-4 dark:bg-gray-700">
<h3 className="mb-2 text-lg font-semibold">
<a href={`/projects/${project.key}`} className="hover:underline">
{project.name}
</a>
</h3>
<a href={`/projects/${project.key}`} className="hover:underline">
<h3 className="mb-2 truncate text-wrap text-lg font-semibold md:text-nowrap">
<TruncatedText text={project.name} />
</h3>
</a>
<div className="flex flex-wrap items-center text-sm text-gray-600 dark:text-gray-300">
<div className="mr-4 flex items-center">
<FontAwesomeIcon icon={faCalendar} className="mr-2 h-4 w-4" />
Expand Down Expand Up @@ -280,22 +281,22 @@ export default function Home() {
)}
/>
</div>
<SecondaryCard title="Recent News & Opinions">
<SecondaryCard title="Recent News & Opinions" className="overflow-hidden">
<div className="grid gap-4 sm:grid-cols-1 md:grid-cols-2">
{data.recentPosts.map((post) => (
<div
key={post.title}
className="rounded-lg bg-gray-200 p-4 dark:bg-gray-700"
className="overflow-hidden rounded-lg bg-gray-200 p-4 dark:bg-gray-700"
data-testid="post-container"
>
<h3 className="mb-1 truncate text-wrap text-lg font-semibold text-blue-500 md:text-nowrap">
<h3 className="mb-1 text-lg font-semibold">
<a
href={post.url}
className="hover:underline"
className="text-blue-500 hover:underline"
target="_blank"
rel="noopener noreferrer"
>
{post.title}
<TruncatedText text={post.title} />
</a>
</h3>
<div className="mt-2 flex flex-col flex-wrap items-start text-sm text-gray-600 dark:text-gray-300 md:flex-row">
Expand Down