Skip to content

Team Chart with YChart Basics#22

Open
mfisher31 wants to merge 6 commits intomieweb:mainfrom
mfisher31:org-chart-initial
Open

Team Chart with YChart Basics#22
mfisher31 wants to merge 6 commits intomieweb:mainfrom
mfisher31:org-chart-initial

Conversation

@mfisher31
Copy link
Copy Markdown
Collaborator

@mfisher31 mfisher31 commented Apr 7, 2026

This change set simply adds ychart to the project, and displays an org chart for the current viewed team on the teams page.

Closes #13

@mfisher31
Copy link
Copy Markdown
Collaborator Author

@rnavyaprabha - and this one too.

@mfisher31 mfisher31 force-pushed the org-chart-initial branch from 7823cc5 to 50d9430 Compare April 8, 2026 14:13
@mfisher31 mfisher31 moved this from Ready to In Progress in Scrum Team Jerry Apr 8, 2026
@mfisher31 mfisher31 self-assigned this Apr 8, 2026
@mfisher31 mfisher31 marked this pull request as ready for review April 8, 2026 15:58
@mfisher31 mfisher31 moved this from In Progress to Review in Scrum Team Jerry Apr 8, 2026
@mfisher31 mfisher31 added the enhancement New feature or request label Apr 8, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds the @mieweb/ychart library to the app and renders an organization chart for the currently selected (non-personal) team on the Teams page.

Changes:

  • Added @mieweb/ychart dependency (and lockfile updates).
  • Rendered a new “Chart” card on TeamsPage for non-personal teams.
  • Introduced TeamChart component that initializes/tears down a YChartEditor org chart view.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.

File Description
package.json Adds @mieweb/ychart dependency.
package-lock.json Lockfile updates to include @mieweb/ychart and its transitive deps (d3, bootstrap, codemirror, etc.).
imports/features/teams/TeamsPage.tsx Renders the chart card and passes derived team/member data into TeamChart.
imports/features/teams/TeamChart.tsx New component that builds YAML and mounts the ychart editor with cleanup logic.

"@fortawesome/free-solid-svg-icons": "^7.0.1",
"@fortawesome/react-fontawesome": "^3.0.2",
"@mieweb/ui": "^0.2.4",
"@mieweb/ychart": "^1.1.0",
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

@mieweb/ychart@1.1.0 declares an npm engine requirement of Node ">=24.0.0" (see package-lock.json entry). This repo targets Meteor 3.5-beta.4 on Node 22, so installs/CI may warn or fail (and the package may use Node 24-only APIs at runtime). Consider using a @mieweb/ychart version that supports Node 22, or otherwise aligning the project/runtime Node version with the dependency’s engine requirement.

Suggested change
"@mieweb/ychart": "^1.1.0",
"@mieweb/ychart": "^1.0.0",

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +68
function buildYaml(teamName: string, members: Member[]): string {
const lines: string[] = [];
lines.push(`- id: 0`);
lines.push(` name: "${teamName}"`);
lines.push(` title: Team`);
members.forEach((m, i) => {
lines.push(`- id: ${i + 1}`);
lines.push(` parentId: 0`);
lines.push(` name: "${m.name}"`);
if (m.isAdmin) lines.push(` title: Admin`);
if (m.email) lines.push(` email: "${m.email}"`);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

buildYaml interpolates team/member names and emails directly into double-quoted YAML scalars. If any value contains quotes, newlines, or other YAML-significant characters, the generated YAML can become invalid (or be interpreted differently than intended). Consider emitting these fields using a safe string escaping/serialization approach (e.g., rely on a YAML serializer, or at minimum use JSON.stringify-style escaping for scalar values).

Suggested change
function buildYaml(teamName: string, members: Member[]): string {
const lines: string[] = [];
lines.push(`- id: 0`);
lines.push(` name: "${teamName}"`);
lines.push(` title: Team`);
members.forEach((m, i) => {
lines.push(`- id: ${i + 1}`);
lines.push(` parentId: 0`);
lines.push(` name: "${m.name}"`);
if (m.isAdmin) lines.push(` title: Admin`);
if (m.email) lines.push(` email: "${m.email}"`);
function yamlDoubleQuoted(value: string): string {
return JSON.stringify(value);
}
function buildYaml(teamName: string, members: Member[]): string {
const lines: string[] = [];
lines.push(`- id: 0`);
lines.push(` name: ${yamlDoubleQuoted(teamName)}`);
lines.push(` title: Team`);
members.forEach((m, i) => {
lines.push(`- id: ${i + 1}`);
lines.push(` parentId: 0`);
lines.push(` name: ${yamlDoubleQuoted(m.name)}`);
if (m.isAdmin) lines.push(` title: Admin`);
if (m.email) lines.push(` email: ${yamlDoubleQuoted(m.email)}`);

Copilot uses AI. Check for mistakes.
Comment on lines +372 to +383
<TeamChart
teamName={selectedTeam.name}
members={selectedTeam.members.map((memberId) => {
const user = members.find((u) => u._id === memberId);
return {
id: memberId,
name: user ? getName(user) : memberId,
email: user?.emails?.[0]?.address,
isAdmin: selectedTeam.admins.includes(memberId),
};
})}
/>
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The members prop for TeamChart is built with a .map() that does a members.find(...) lookup for each memberId, making this O(n^2) for larger teams. Consider precomputing a Map of userId → user once (e.g., via useMemo) and doing O(1) lookups inside the map, especially since this runs on every render of TeamsPage.

Suggested change
<TeamChart
teamName={selectedTeam.name}
members={selectedTeam.members.map((memberId) => {
const user = members.find((u) => u._id === memberId);
return {
id: memberId,
name: user ? getName(user) : memberId,
email: user?.emails?.[0]?.address,
isAdmin: selectedTeam.admins.includes(memberId),
};
})}
/>
{(() => {
const membersById = new Map(members.map((member) => [member._id, member]));
return (
<TeamChart
teamName={selectedTeam.name}
members={selectedTeam.members.map((memberId) => {
const user = membersById.get(memberId);
return {
id: memberId,
name: user ? getName(user) : memberId,
email: user?.emails?.[0]?.address,
isAdmin: selectedTeam.admins.includes(memberId),
};
})}
/>
);
})()}

Copilot uses AI. Check for mistakes.
Comment on lines +147 to +150
export const TeamChart: React.FC<TeamChartProps> = ({ teamName, members }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
const yaml = useMemo(() => buildYaml(teamName, members), [teamName, JSON.stringify(members)]);
const wrapperRef = useRef<HTMLDivElement>(null);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The yaml memoization depends on JSON.stringify(members), which re-serializes the entire members array every render and is sensitive to ordering/serialization quirks. This can become a noticeable cost for larger teams and can be brittle. Prefer stabilizing the members prop upstream (so [teamName, members] works), or derive a lightweight stable dependency (e.g., a precomputed hash/id list) rather than JSON.stringify in the dependency array.

Copilot uses AI. Check for mistakes.
Comment on lines 52 to 56
import { useTeam } from '../../lib/TeamContext';
import { useMethod } from '../../lib/useMethod';
import { Teams } from './api';
import { TeamChart } from './TeamChart';

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

Importing TeamChart (and transitively @mieweb/ychart + d3) at the top level means this heavy charting bundle is pulled into the initial /app client bundle, even for users who never visit the Teams page (AppLayout statically imports TeamsPage). Consider lazy-loading TeamChart (or at least the @mieweb/ychart side-effect import) so the chart code only loads when the Teams page/chart section is actually rendered.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Review

Development

Successfully merging this pull request may close these issues.

Organization Chart Initial

2 participants