* refactor: migrate web icons to @makeplane/propel
Replace confirmed icon symbols across apps/web with their audited
@makeplane/propel/icons targets. Unresolved symbols and the State,
Priority and Brand icons stay on their existing imports.
Lucide size props become explicit width/height, including the two
relation icons and the inbox status icon that forward a size variable.
Two aliased imports resolve to targets the file already imported, so
the aliases are dropped rather than importing the same symbol twice.
Widen the member dropdown chain and the AI menu from LucideIcon to
ComponentType<SVGProps<SVGSVGElement>> so both Lucide and Propel icons
satisfy them; both only ever render the icon with a className.
CycleGroupIcon is deliberately not migrated: it dispatches a different
glyph and color per cycle status, which CyclesOutline cannot express.
apps/web already declared @makeplane/propel, so no dependency change
was needed.
* fix: address icon migration review on web
Restore the six user-facing strings the identifier rename overwrote.
The migration replaced every occurrence of a source symbol name,
including ones inside string literals and JSX text, so the GitHub
empty state read "StarOutline us on GitHub", the exporter column key,
header and button label became "DownloadOutline", the project card
action title became "SettingsOutline" and a tooltip became "PinOutline".
Drop 122 strokeWidth props and 10 text-2 classes. Propel glyphs paint
with fill="currentColor", so strokeWidth never changed weight, and
text-2 was a bad conversion of stroke-2, which is a stroke width rather
than a colour and has no meaning on a fill path.
Use StarFilled for the two favorited sidebar stars. Lucide's Star with
fill-yellow-500 was a solid star, and StarOutline is a ring path, so
filling it does not reproduce that shape.
* refactor: migrate web @plane/propel Tooltip to @makeplane/propel
Move all 144 Tooltip call sites in apps/web from the in-repo
@plane/propel/tooltip to the published
@makeplane/propel/components/tooltip.
Prop mapping applied on every site:
- tooltipContent -> label (string)
- tooltipHeading -> folded into label + layout="stacked"
- position -> side/align (top/center omitted; it is the published default)
- isMobile -> disabled (OR'd with any existing disabled)
- renderByDefault -> dropped; the in-repo Tooltip declared but never
used it
- className -> dropped, or mapped to sideOffset/alignOffset (3 sites)
layout is "single" for short bounded copy and "stacked" wherever the
label interpolates unbounded data (names, titles, URLs, joined lists) —
"single" is whitespace-nowrap, so long labels would overflow.
Behavior change: tooltips now open after the published 600ms default
instead of the in-repo 200ms. delay is deliberately not set per site.
ReactNode content:
- Editor toolbars map name + <kbd>shortcut</kbd> onto the published
shortcut prop
- <br/> and fragment copy folds into one wrapping stacked string
- stickies/action-bar rendered a full <StickyNote> hover preview, not a
tooltip; it moves to PreviewCard/PreviewCardTrigger/PreviewCardContent
Published label is a string, so DropdownButtonProps.tooltipContent,
date-range's customTooltipContent, and the two rich-filters components
narrow from ReactNode to string. rich-filters/root.tsx guards
filterConfig.tooltipContent, which stays ReactNode in @plane/types.
Folded labels use ?? "" where the source expression is nullable so they
cannot render the string "undefined" where the in-repo tooltip rendered
nothing.
Zero @plane/propel/tooltip references remain under apps/web.
* fix: address review findings on the Tooltip migration
Accessibility (CodeRabbit): Base UI wires no aria-describedby or
aria-labelledby between the tooltip trigger and its popup — verified by
rendering the published Tooltip and inspecting the DOM, the trigger comes
out as `<button data-base-ui-tooltip-trigger>` with no aria at all and the
popup has role="tooltip" but no id. So a `label` never reaches assistive
tech, and the four icon-only triggers announced as bare "button". Add an
explicit aria-label at each: extended-project-sidebar, layout-switcher,
layout-selection, and access-field. Pre-existing gap (the in-repo tooltip
sat on the same unwired Base UI trigger), fixed here since the PR touches
these sites.
AccessField now requires i18n_label and drops the optional pre-i18n
`label`, so the computed label is non-empty by construction and serves as
both the tooltip copy and the accessible name. Its only caller already
passes i18n_label for every specifier, which also retires the TODO.
Correctness: inbox issue-properties interpolated a nullable name into a
template literal, so a duplicate work item with no name rendered the
literal "undefined"; pass the name with ?? "" instead.
CodeQL useless conditional: drop `|| ""` from stickyId in action-bar —
both call sites already sit behind a guard proving recentStickyId truthy,
and StickyNote treats "" and undefined identically.
React Doctor prefer-module-scope-static-value: hoist badgeContent to
module scope as BADGE_CONTENT; it holds only static strings.
React Doctor js-combine-iterations: collapse the filter/map chains to a
single pass. The two layout switchers skip inside map instead of
pre-filtering; LabelSummary reduces project labels into the selected
names once rather than filter -> map -> join.
Replace @plane/ui Input in apps/web with Propel Input and InputGroup.
hasError maps to Field invalid. Default size is 2xl to match the old h-10 height.
* refactor: migrate web ToggleSwitch to @makeplane/propel Switch
Replace @plane/ui ToggleSwitch with @makeplane/propel Switch in apps/web.
Wire the package on web and import Propel styles so Switch utilities emit.
* style: fix comboButton indentation in dropdowns
* chore: use workspace catalog for @makeplane/propel
* chore: remove posthog integration and analytics scaffold
Removes the PostHog integration end to end, plus the inert autocapture
scaffold left behind by an earlier partial removal (d61b157929,
"chore: remove posthog events (#8465)").
Backend:
- delete bgtasks/event_tracking_task.py and utils/analytics_events.py
- drop all 6 track_event.delay call sites
- drop POSTHOG_API_KEY / POSTHOG_HOST settings
- stop returning posthog_api_key / posthog_host from GET /api/instances/
- drop the posthog==3.5.0 dependency
Frontend:
- delete packages/constants/src/event-tracker (all 40 exports were unused)
- remove 42 data-ph-element attributes across 36 files
- remove the dead shouldTrackEvents and trackerElements prop chains
- remove the Microsoft Clarity session-recording tag
Note: GET /api/instances/ no longer returns posthog_api_key/posthog_host.
Nothing in this repo read them and neither do plane-ee or plane-commercial,
but the endpoint is AllowAny and cached for 2h.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HD7dTidmtWWRRiFv3nmW3s
* chore: apply oxfmt formatting
Collapse JSX elements and import statements that were left multi-line
after the tracker props and specifiers were removed. Whitespace only.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HD7dTidmtWWRRiFv3nmW3s
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Add jscodeshift-based codemod to convert arrow function components to function declarations
- Support React.FC, observer-wrapped, and forwardRef components
- Include comprehensive test suite covering edge cases
- Add npm script to run transformer across codebase
- Target only .tsx files in source directories, excluding node_modules and declaration files
* [WEB-5459] chore: updates after running codemod
---------
Co-authored-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
* [WEB-5134] refactor: update `web` ESLint configuration and refactor imports to use type imports
- Enhanced ESLint configuration by adding new rules for import consistency and type imports.
- Refactored multiple files to replace regular imports with type imports for better clarity and performance.
- Ensured consistent use of type imports across the application to align with TypeScript best practices.
* refactor: standardize type imports across components
- Updated multiple files to replace regular imports with type imports for improved clarity and consistency.
- Ensured adherence to TypeScript best practices in the rich filters and issue layouts components.