Skip to content

Conversation

@emlimlf
Copy link
Collaborator

@emlimlf emlimlf commented Dec 10, 2024

Changes proposed ✍️

What

Implemented a new timeline UI for the contributor's work history based on this design: https://www.figma.com/design/IKlC7mpFdr0GtiSH182KIX/1.-LFX-CM-%7C-Product---Core?node-id=1571-37749&node-type=frame&t=6kxre7hEcRK031S6-0

Why

To improve the work history section, we will display the organizations and roles similar to what LinkedIn does.

Ticket: https://linear.app/lfx/issue/LFX-1843/improve-work-history-timeline

Checklist ✅

  • Label appropriately with Feature, Improvement, or Bug.
  • Add screenshots to the PR description for relevant FE changes
  • New backend functionality has been unit-tested.
  • API documentation has been updated (if necessary) (see docs on API documentation).
  • Quality standards are met.

Summary by CodeRabbit

  • New Features

    • Introduced a structured timeline format for displaying contributor work history.
    • Added new components for timeline representation: LfTimeline and LfTimelineItem.
    • Created a new interface for organizing timeline data.
  • Bug Fixes

    • Enhanced error handling for displaying messages when no work experiences are available.
  • Style

    • Implemented new styles for the timeline component, improving visual organization.
  • Documentation

    • Added Storybook configuration for the LfTimeline component to showcase its usage.

Signed-off-by: Efren Lim <[email protected]>
Signed-off-by: Efren Lim <[email protected]>
@emlimlf emlimlf requested a review from joanagmaia December 10, 2024 00:13
@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes in this pull request introduce a new timeline format for displaying work history in the contributor-details-work-history.vue component. This format replaces the previous list view and utilizes a computed property to group organizations. The contributor-details-work-history-item.vue component has been simplified by removing the avatar and focusing on membership details. Additionally, new components for the timeline interface, including LfTimeline and LfTimelineItem, have been created, along with associated styles and types. A Storybook configuration for the timeline component has also been added.

Changes

File Change Summary
frontend/src/modules/contributor/components/details/contributor-details-work-history.vue Introduced computed properties for organization grouping and updated display logic for work history.
frontend/src/modules/contributor/components/details/work-history/contributor-details-work-history-item.vue Removed avatar and router link, simplified template to focus on membership details.
frontend/src/ui-kit/timeline/Timeline.vue Added LfTimeline component to render a timeline interface with groups and customizable slots.
frontend/src/ui-kit/timeline/TimelineItem.vue Introduced LfTimelineItem component for individual timeline items with flexible content.
frontend/src/ui-kit/timeline/Timeline.stories.ts Created Storybook configuration for LfTimeline with a new story for rendering timeline groups.
frontend/src/ui-kit/timeline/timeline.scss Added styles for the timeline component using Tailwind CSS utility classes.
frontend/src/ui-kit/timeline/types/TimelineTypes.ts Introduced TimelineGroup interface to define the structure for timeline groups.

Possibly related PRs

  • Bugfix/lfx 1803 people tab org #2696: The changes in contributor-details-work-history.vue involve a new timeline format that enhances the display of work history, which is conceptually related to the activity count integration and new column addition in the organization profile overview page addressed in this PR.

Suggested reviewers

  • joanagmaia
  • themarolt

Poem

🐇 In the timeline, we hop and play,
With work stories grouped in a new way.
No more avatars, just titles so bright,
Each experience shared, a beautiful sight!
So let’s celebrate this change today,
A joyful leap in our work display! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (9)
frontend/src/modules/contributor/components/details/contributor-details-work-history.vue (2)

94-95: Consider replacing lodash's groupBy with native JavaScript.

Using lodash's groupBy function adds an external dependency. You can achieve the same functionality with native JavaScript, which can help reduce bundle size and improve performance.

Here's how you can use native JavaScript to group the organizations:

const grouped = props.contributor.organizations.reduce((acc, organization) => {
  const key = organization.id;
  if (!acc[key]) {
    acc[key] = [];
  }
  acc[key].push(organization);
  return acc;
}, {});

130-137: Simplify the logic in minimumShownGroups computation.

The computation for minimumShownGroups is somewhat complex and might be hard to understand at first glance. Simplifying it or adding comments can improve code readability and maintainability.

Consider this simplified version:

const minimumShownGroups = computed(() => {
  const MIN_ITEMS = 3;
  return Math.min(orgGrouped.value.length, MIN_ITEMS);
});

If more complex logic is necessary, adding explanatory comments would be beneficial.

frontend/src/ui-kit/timeline/Timeline.vue (3)

2-2: Consider adding aria-label for accessibility

The timeline structure should be more accessible to screen readers.

-  <div v-for="group in props.groups" :key="group.label" class="c-timeline">
+  <div v-for="group in props.groups" :key="group.label" class="c-timeline" role="list" aria-label="Timeline">

13-24: Add title attribute for truncated text

Since the group label might be truncated in some cases (as seen in the story), it would be helpful to show the full text on hover.

-          {{ group.label }}
+          <span :title="group.label">{{ group.label }}</span>

37-39: Consider type-safe props definition

The props interface could be more specific about the expected types.

-const props = defineProps<{
-  groups: TimelineGroup[];
-}>();
+interface TimelineProps {
+  groups: TimelineGroup[];
+}
+const props = defineProps<TimelineProps>();
frontend/src/ui-kit/timeline/Timeline.stories.ts (1)

20-27: Improve readability of sample data

The sample data is too condensed and hard to read. Consider formatting it for better readability.

-    groups: [
-      {
-        label: 'Group 1', labelLink: { name: 'organizationView', params: { id: '1' } }, icon: 'https://avatars.githubusercontent.com/u/38015056?v=4', items: [{ id: 1, label: 'Item 1', date: 'Aug 2024 - Dec 2024' }, { id: 2, label: 'Item 2', date: 'Aug 2024' }, { id: 3, label: 'Item 3', date: 'Aug 2024' }, { id: 4, label: 'Item 4', date: 'Aug 2024' }],
-      },
-      {
-        label: 'Group 2', labelLink: { name: 'organizationView', params: { id: '2' } }, icon: 'https://avatars.githubusercontent.com/u/38015056?v=4', items: [{ id: 3, label: 'Item 3', date: 'Aug 2024' }, { id: 4, label: 'Item 4', date: 'Aug 2024' }],
-      },
-    ],
+    groups: [
+      {
+        label: 'Group 1',
+        labelLink: { name: 'organizationView', params: { id: '1' } },
+        icon: 'https://avatars.githubusercontent.com/u/38015056?v=4',
+        items: [
+          { id: 1, label: 'Item 1', date: 'Aug 2024 - Dec 2024' },
+          { id: 2, label: 'Item 2', date: 'Aug 2024' },
+          { id: 3, label: 'Item 3', date: 'Aug 2024' },
+          { id: 4, label: 'Item 4', date: 'Aug 2024' }
+        ],
+      },
+      {
+        label: 'Group 2',
+        labelLink: { name: 'organizationView', params: { id: '2' } },
+        icon: 'https://avatars.githubusercontent.com/u/38015056?v=4',
+        items: [
+          { id: 3, label: 'Item 3', date: 'Aug 2024' },
+          { id: 4, label: 'Item 4', date: 'Aug 2024' }
+        ],
+      },
+    ],
frontend/src/modules/contributor/components/details/work-history/contributor-details-work-history-item.vue (3)

Line range hint 7-14: Improve accessibility of truncated text

The truncated text with hardcoded max-width might not be responsive and accessible.

-          <p class="truncate" style="max-width: 30ch">
+          <p class="truncate max-w-[30ch]" :title="props.organization?.memberOrganizations?.title">

Line range hint 19-40: Enhance dropdown menu accessibility

The dropdown menu is only accessible via hover, which may cause issues for keyboard and screen reader users.

-      <lf-dropdown v-if="hovered" placement="bottom-end" width="14.5rem">
+      <lf-dropdown 
+        v-if="hovered" 
+        placement="bottom-end" 
+        width="14.5rem"
+        role="menu"
+        aria-label="Work experience actions"
+      >
         <template #trigger>
-          <lf-button type="secondary-ghost" size="small" :icon-only="true">
+          <lf-button 
+            type="secondary-ghost" 
+            size="small" 
+            :icon-only="true"
+            aria-label="More actions"
+            @keydown.enter="hovered = true"
+          >

Line range hint 92-106: Consider extracting date formatting logic

The date formatting logic could be moved to a separate utility function for reusability and easier testing.

Consider creating a new file utils/date-formatter.ts:

export const formatDateRange = (dateStart?: string, dateEnd?: string, format: string = 'MMMM YYYY'): string => {
  const start = dateStart
    ? moment(dateStart).utc().format(format)
    : 'Unknown';
  const endDefault = dateStart ? 'Present' : 'Unknown';
  const end = dateEnd
    ? moment(dateEnd).utc().format(format)
    : endDefault;
  return start === end ? start : `${start}${end}`;
};

Then update the component to use this utility:

-const getDateRange = (dateStart?: string, dateEnd?: string) => {
-  const start = dateStart
-    ? moment(dateStart).utc().format('MMMM YYYY')
-    : 'Unknown';
-  const endDefault = dateStart ? 'Present' : 'Unknown';
-  const end = dateEnd
-    ? moment(dateEnd).utc().format('MMMM YYYY')
-    : endDefault;
-  if (start === end) {
-    return start;
-  }
-  return `${start} → ${end}`;
-};
+import { formatDateRange } from '@/utils/date-formatter';
+const getDateRange = formatDateRange;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b36c93d and cfb3f4e.

📒 Files selected for processing (7)
  • frontend/src/modules/contributor/components/details/contributor-details-work-history.vue (3 hunks)
  • frontend/src/modules/contributor/components/details/work-history/contributor-details-work-history-item.vue (1 hunks)
  • frontend/src/ui-kit/timeline/Timeline.stories.ts (1 hunks)
  • frontend/src/ui-kit/timeline/Timeline.vue (1 hunks)
  • frontend/src/ui-kit/timeline/TimelineItem.vue (1 hunks)
  • frontend/src/ui-kit/timeline/timeline.scss (1 hunks)
  • frontend/src/ui-kit/timeline/types/TimelineTypes.ts (1 hunks)
🔇 Additional comments (1)
frontend/src/ui-kit/timeline/timeline.scss (1)

1-38: Well-structured SCSS using Tailwind CSS utilities.

The SCSS for the timeline component is organized and effectively utilizes Tailwind CSS utility classes for styling. This approach maintains consistency and simplifies maintenance.

Copy link
Contributor

@joanagmaia joanagmaia left a comment

Choose a reason for hiding this comment

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

Hey Efren 👋
I've listed most of the issues in the PR, but also left a video if it helps a bit more
Let me know if you have any questions
https://www.loom.com/share/2c68c000858f42e6851b521978a61b60?sid=ca64433b-8abb-4d13-b8ce-3a29120be4bc

Comment on lines 40 to 42
<p class="truncate" style="max-width: 30ch">
{{ item.label }}
</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

This should have by default a text-gray-900 color, and only on hover a blue one (link behaviour)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is just a sample content inside the timeline component. You can theoretically use anything inside the content of the lf-timeline-item. I've added the text-gray-900 anyway.

}));
});
const minimumShownGroups = computed(() => {
const MIN_ITEMS = 3;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you confirm that this logic is working? If you check the video I have 3 organizations but only 2 are showing.
By default we should always show 3 organizations regardless of how many titles we have for each one of them

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I sent a message through slack regarding this. I reverted this anyway to the old fixed 3 organization limit regardless of how many roles the contributor had in that org.

</router-link>

<div class="flex flex-auto flex-col overflow-hidden">
<div v-if="props.organization?.memberOrganizations?.title" class="text-small text-gray-500 mb-1.5 flex items-center gap-1.5">
Copy link
Contributor

Choose a reason for hiding this comment

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

This color should be updated to text-gray-900

@emlimlf
Copy link
Collaborator Author

emlimlf commented Dec 12, 2024

@joanagmaia I've addressed the items you highlighted

Copy link
Contributor

@joanagmaia joanagmaia left a comment

Choose a reason for hiding this comment

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

All good. Just one last fix:
We shouldn't exceed the width of that section.
Check image 2 - "..." button is vertically aligned with "+" button.
Check image 1 - since job title is big, the "..." button is overflowing the section, there's also no space between the title and the button

So we should:

  • Have a gap space between title and button
  • truncate job title to prevent the item from overflowing the section

Screenshot 2024-12-13 at 14 20 13
Screenshot 2024-12-13 at 14 20 18

@emlimlf
Copy link
Collaborator Author

emlimlf commented Dec 16, 2024

@joanagmaia I've pushed an update to fix that last bit you highlighted.

@joanagmaia joanagmaia merged commit 81832aa into main Dec 16, 2024
6 checks passed
@joanagmaia joanagmaia deleted the feature/LFX-1843-work-history branch December 16, 2024 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants