mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-21 21:49:51 +01:00
fix: react rule of hooks linting to error (#25232)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
af23230b97
commit
d09bfce3d7
@ -52,7 +52,7 @@ module.exports = {
|
||||
'unused-imports',
|
||||
],
|
||||
rules: {
|
||||
"react-hooks/rules-of-hooks": "warn",
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
// PyCharm always adds curly braces, I guess vscode doesn't, PR reviewers often complain they are present on props that don't need them
|
||||
// let's save the humans time and let the machines do the work
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 161 KiB |
Binary file not shown.
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
@ -41,6 +41,7 @@ async function testSetup(
|
||||
scope: ActivityScope,
|
||||
url: string
|
||||
): Promise<ReturnType<typeof activityLogLogic.build>> {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useMocks({
|
||||
get: {
|
||||
[url]: {
|
||||
|
@ -11,6 +11,7 @@ export function AlertDeletionWarning(): JSX.Element | null {
|
||||
return null
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { shouldShowAlertDeletionWarning } = useValues(
|
||||
alertsLogic({
|
||||
insightShortId: insight.short_id,
|
||||
|
@ -479,13 +479,6 @@ export function ControlledDefinitionPopover({
|
||||
group,
|
||||
highlightedItemElement,
|
||||
}: ControlledDefinitionPopoverContentsProps): JSX.Element | null {
|
||||
// Supports all types specified in selectedItemHasPopover
|
||||
const value = group.getValue?.(item)
|
||||
|
||||
if (!value || !item) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { state, singularType, definition } = useValues(definitionPopoverLogic)
|
||||
const { setDefinition } = useActions(definitionPopoverLogic)
|
||||
|
||||
@ -497,6 +490,13 @@ export function ControlledDefinitionPopover({
|
||||
setDefinition(item)
|
||||
}, [item])
|
||||
|
||||
// Supports all types specified in selectedItemHasPopover
|
||||
const value = group.getValue?.(item)
|
||||
|
||||
if (!value || !item) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover
|
||||
visible={visible}
|
||||
|
@ -50,6 +50,7 @@ export function LemonCollapse<K extends React.Key>({
|
||||
let isPanelExpanded: (key: K) => boolean
|
||||
let onPanelChange: (key: K, isExpanded: boolean) => void
|
||||
if (props.multiple) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const [localActiveKeys, setLocalActiveKeys] = useState<Set<K>>(new Set(props.defaultActiveKeys ?? []))
|
||||
const effectiveActiveKeys = props.activeKeys ? new Set(props.activeKeys) : localActiveKeys
|
||||
isPanelExpanded = (key: K) => effectiveActiveKeys.has(key)
|
||||
@ -64,6 +65,7 @@ export function LemonCollapse<K extends React.Key>({
|
||||
setLocalActiveKeys(newActiveKeys)
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const [localActiveKey, setLocalActiveKey] = useState<K | null>(props.defaultActiveKey ?? null)
|
||||
const effectiveActiveKey = props.activeKey ?? localActiveKey
|
||||
isPanelExpanded = (key: K) => key === effectiveActiveKey
|
||||
|
@ -46,6 +46,7 @@ export const ToastTypes: Story = {
|
||||
render: (args, { globals }) => {
|
||||
const isDarkModeOn = globals.theme === 'dark'
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
lemonToast.dismiss()
|
||||
args.toasts.forEach((toast) => {
|
||||
|
@ -134,16 +134,9 @@ export const AllProductsPlanComparison = ({
|
||||
product: BillingProductV2Type
|
||||
includeAddons?: boolean
|
||||
}): JSX.Element | null => {
|
||||
const plans = product.plans?.filter(
|
||||
(plan) => !plan.included_if || plan.included_if == 'has_subscription' || plan.current_plan
|
||||
)
|
||||
if (plans?.length === 0) {
|
||||
return null
|
||||
}
|
||||
const { billing, redirectPath, timeRemainingInSeconds, timeTotalInSeconds } = useValues(billingLogic)
|
||||
const { ref: planComparisonRef } = useResizeObserver()
|
||||
const { reportBillingUpgradeClicked, reportBillingDowngradeClicked } = useActions(eventUsageLogic)
|
||||
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
|
||||
const { surveyID, comparisonModalHighlightedFeatureKey, billingProductLoading } = useValues(
|
||||
billingProductLogic({ product })
|
||||
)
|
||||
@ -152,6 +145,14 @@ export const AllProductsPlanComparison = ({
|
||||
)
|
||||
const { featureFlags } = useValues(featureFlagLogic)
|
||||
|
||||
const plans = product.plans?.filter(
|
||||
(plan) => !plan.included_if || plan.included_if == 'has_subscription' || plan.current_plan
|
||||
)
|
||||
if (plans?.length === 0) {
|
||||
return null
|
||||
}
|
||||
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
|
||||
|
||||
const nonInclusionProducts = billing?.products.filter((p) => !p.inclusion_only) || []
|
||||
const inclusionProducts = billing?.products.filter((p) => !!p.inclusion_only) || []
|
||||
const sortedProducts = nonInclusionProducts
|
||||
|
@ -112,17 +112,9 @@ export const PlanComparison = ({
|
||||
product: BillingProductV2Type
|
||||
includeAddons?: boolean
|
||||
}): JSX.Element | null => {
|
||||
const plans = product.plans?.filter(
|
||||
(plan) => !plan.included_if || plan.included_if == 'has_subscription' || plan.current_plan
|
||||
)
|
||||
if (plans?.length === 0) {
|
||||
return null
|
||||
}
|
||||
const fullyFeaturedPlan = plans[plans.length - 1]
|
||||
const { billing, redirectPath, timeRemainingInSeconds, timeTotalInSeconds } = useValues(billingLogic)
|
||||
const { width, ref: planComparisonRef } = useResizeObserver()
|
||||
const { reportBillingUpgradeClicked, reportBillingDowngradeClicked } = useActions(eventUsageLogic)
|
||||
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
|
||||
const { surveyID, comparisonModalHighlightedFeatureKey, billingProductLoading } = useValues(
|
||||
billingProductLogic({ product })
|
||||
)
|
||||
@ -131,6 +123,15 @@ export const PlanComparison = ({
|
||||
)
|
||||
const { featureFlags } = useValues(featureFlagLogic)
|
||||
|
||||
const plans = product.plans?.filter(
|
||||
(plan) => !plan.included_if || plan.included_if == 'has_subscription' || plan.current_plan
|
||||
)
|
||||
if (plans?.length === 0) {
|
||||
return null
|
||||
}
|
||||
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
|
||||
const fullyFeaturedPlan = plans[plans.length - 1]
|
||||
|
||||
const ctaAction = billing?.subscription_level === 'custom' ? 'Subscribe' : 'Upgrade'
|
||||
const upgradeButtons = plans?.map((plan, i) => {
|
||||
return (
|
||||
|
@ -620,6 +620,7 @@ function UsageTab({ featureFlag }: { id: string; featureFlag: FeatureFlagType })
|
||||
let dashboard: DashboardType<QueryBasedInsightModel> | null = null
|
||||
if (dashboardId) {
|
||||
// FIXME: Refactor out into <ConnectedDashboard />, as React hooks under conditional branches are no good
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const dashboardLogicValues = useValues(
|
||||
dashboardLogic({ id: dashboardId, placement: DashboardPlacement.FeatureFlag })
|
||||
)
|
||||
|
@ -11,15 +11,14 @@ import { teamLogic } from 'scenes/teamLogic'
|
||||
import { urls } from 'scenes/urls'
|
||||
|
||||
import { cohortsModel } from '~/models/cohortsModel'
|
||||
import { groupsModel } from '~/models/groupsModel'
|
||||
import { FeatureFlagType, OrganizationFeatureFlag } from '~/types'
|
||||
import { groupsModel, type Noun } from '~/models/groupsModel'
|
||||
import { CohortType, FeatureFlagType, OrganizationFeatureFlag, OrganizationType } from '~/types'
|
||||
|
||||
import { organizationLogic } from '../organizationLogic'
|
||||
import { featureFlagLogic } from './featureFlagLogic'
|
||||
import { groupFilters } from './FeatureFlags'
|
||||
|
||||
function checkHasStaticCohort(featureFlag: FeatureFlagType): boolean {
|
||||
const { cohorts } = useValues(cohortsModel)
|
||||
function checkHasStaticCohort(featureFlag: FeatureFlagType, cohorts: CohortType[]): boolean {
|
||||
const staticCohorts = new Set()
|
||||
cohorts.forEach((cohort) => {
|
||||
if (cohort.is_static) {
|
||||
@ -37,11 +36,15 @@ function checkHasStaticCohort(featureFlag: FeatureFlagType): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
const getColumns = (): LemonTableColumns<OrganizationFeatureFlag> => {
|
||||
const { currentTeamId } = useValues(teamLogic)
|
||||
const { currentOrganization } = useValues(organizationLogic)
|
||||
const { aggregationLabel } = useValues(groupsModel)
|
||||
|
||||
const getColumns = ({
|
||||
aggregationLabel,
|
||||
currentTeamId,
|
||||
currentOrganization,
|
||||
}: {
|
||||
aggregationLabel: (groupTypeIndex: number | null | undefined, deferToUserWording?: boolean) => Noun
|
||||
currentTeamId: number | null
|
||||
currentOrganization: OrganizationType | null
|
||||
}): LemonTableColumns<OrganizationFeatureFlag> => {
|
||||
return [
|
||||
{
|
||||
title: 'Project',
|
||||
@ -133,8 +136,9 @@ function FeatureFlagCopySection(): JSX.Element {
|
||||
const { setCopyDestinationProject, copyFlag } = useActions(featureFlagLogic)
|
||||
const { currentOrganization } = useValues(organizationLogic)
|
||||
const { currentTeam } = useValues(teamLogic)
|
||||
const { cohorts } = useValues(cohortsModel)
|
||||
|
||||
const hasStaticCohort = checkHasStaticCohort(featureFlag)
|
||||
const hasStaticCohort = checkHasStaticCohort(featureFlag, cohorts)
|
||||
const hasMultipleProjects = (currentOrganization?.teams?.length ?? 0) > 1
|
||||
|
||||
return hasMultipleProjects && featureFlag.can_edit ? (
|
||||
@ -198,6 +202,9 @@ function FeatureFlagCopySection(): JSX.Element {
|
||||
export default function FeatureFlagProjects(): JSX.Element {
|
||||
const { projectsWithCurrentFlag } = useValues(featureFlagLogic)
|
||||
const { loadProjectsWithCurrentFlag } = useActions(featureFlagLogic)
|
||||
const { currentTeamId } = useValues(teamLogic)
|
||||
const { currentOrganization } = useValues(organizationLogic)
|
||||
const { aggregationLabel } = useValues(groupsModel)
|
||||
|
||||
useEffect(() => {
|
||||
loadProjectsWithCurrentFlag()
|
||||
@ -210,7 +217,7 @@ export default function FeatureFlagProjects(): JSX.Element {
|
||||
<LemonTable
|
||||
loading={false}
|
||||
dataSource={projectsWithCurrentFlag}
|
||||
columns={getColumns()}
|
||||
columns={getColumns({ currentTeamId, currentOrganization, aggregationLabel })}
|
||||
emptyState="This feature flag is not being used in any other project."
|
||||
/>
|
||||
</div>
|
||||
|
@ -45,6 +45,9 @@ export function AggregationSelect({
|
||||
const { querySource } = useValues(insightVizDataLogic(insightProps))
|
||||
const { updateQuerySource } = useActions(insightVizDataLogic(insightProps))
|
||||
|
||||
const { groupTypes, aggregationLabel } = useValues(groupsModel)
|
||||
const { needsUpgradeForGroups, canStartUsingGroups } = useValues(groupsAccessLogic)
|
||||
|
||||
if (!isInsightQueryNode(querySource)) {
|
||||
return null
|
||||
}
|
||||
@ -64,8 +67,6 @@ export function AggregationSelect({
|
||||
updateQuerySource({ aggregation_group_type_index: groupIndex } as FunnelsQuery)
|
||||
}
|
||||
}
|
||||
const { groupTypes, aggregationLabel } = useValues(groupsModel)
|
||||
const { needsUpgradeForGroups, canStartUsingGroups } = useValues(groupsAccessLogic)
|
||||
|
||||
const baseValues = [UNIQUE_USERS]
|
||||
const optionSections: LemonSelectSection<string>[] = [
|
||||
|
@ -145,6 +145,8 @@ const cleanBreakdownParams = (cleanedParams: Partial<FilterType>, filters: Parti
|
||||
// For the map, make sure we are breaking down by country
|
||||
// Support automatic switching to country code breakdown both from no breakdown and from country name breakdown
|
||||
cleanedParams['breakdown'] = '$geoip_country_code'
|
||||
// this isn't a react hook
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useMostRelevantBreakdownType(cleanedParams, filters)
|
||||
return
|
||||
}
|
||||
|
@ -112,10 +112,12 @@ export function PersonDisplay({
|
||||
) : (
|
||||
<Popover
|
||||
overlay={
|
||||
<PersonPreview
|
||||
distinctId={person?.distinct_id || person?.distinct_ids?.[0]}
|
||||
onClose={() => setVisible(false)}
|
||||
/>
|
||||
person?.distinct_id || person?.distinct_ids?.[0] ? (
|
||||
<PersonPreview
|
||||
distinctId={person?.distinct_id || person?.distinct_ids?.[0]}
|
||||
onClose={() => setVisible(false)}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
visible={visible}
|
||||
onClickOutside={() => setVisible(false)}
|
||||
|
@ -21,7 +21,7 @@ export function PersonPreview(props: PersonPreviewProps): JSX.Element | null {
|
||||
if (!props.distinctId) {
|
||||
return null
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { person, personLoading } = useValues(personLogic({ id: props.distinctId }))
|
||||
|
||||
if (personLoading) {
|
||||
|
@ -262,6 +262,7 @@ function pluginMenuItems(node: PluginBasedNode): LemonMenuItem[] {
|
||||
}
|
||||
|
||||
export function pipelineNodeMenuCommonItems(node: Transformation | SiteApp | ImportApp | Destination): LemonMenuItem[] {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { canConfigurePlugins } = useValues(pipelineAccessLogic)
|
||||
|
||||
const items: LemonMenuItem[] = [
|
||||
@ -295,6 +296,7 @@ export function pipelinePluginBackedNodeMenuCommonItems(
|
||||
loadPluginConfigs: any,
|
||||
inOverview?: boolean
|
||||
): LemonMenuItem[] {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { canConfigurePlugins } = useValues(pipelineAccessLogic)
|
||||
|
||||
return [
|
||||
|
@ -176,7 +176,8 @@ const MenuActions = (): JSX.Element => {
|
||||
useActions(sessionRecordingPlayerLogic)
|
||||
const { fetchSimilarRecordings } = useActions(sessionRecordingDataLogic(logicProps))
|
||||
|
||||
const hasMobileExport = window.IMPERSONATED_SESSION || useFeatureFlag('SESSION_REPLAY_EXPORT_MOBILE_DATA')
|
||||
const hasMobileExportFlag = useFeatureFlag('SESSION_REPLAY_EXPORT_MOBILE_DATA')
|
||||
const hasMobileExport = window.IMPERSONATED_SESSION || hasMobileExportFlag
|
||||
const hasSimilarRecordings = useFeatureFlag('REPLAY_SIMILAR_RECORDINGS')
|
||||
|
||||
const onDelete = (): void => {
|
||||
|
@ -145,14 +145,14 @@ export function Members(): JSX.Element | null {
|
||||
const { preflight } = useValues(preflightLogic)
|
||||
const { user } = useValues(userLogic)
|
||||
|
||||
if (!user) {
|
||||
return null
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
ensureAllMembersLoaded()
|
||||
}, [])
|
||||
|
||||
if (!user) {
|
||||
return null
|
||||
}
|
||||
|
||||
const columns: LemonTableColumns<OrganizationMemberType> = [
|
||||
{
|
||||
key: 'user_profile_picture',
|
||||
|
@ -95,7 +95,8 @@ export function ToolbarInfoMenu(): JSX.Element | null {
|
||||
const { visibleMenu, isDragging, menuProperties, minimized, isBlurred } = useValues(toolbarLogic)
|
||||
const { setMenu } = useActions(toolbarLogic)
|
||||
const { isAuthenticated } = useValues(toolbarConfigLogic)
|
||||
const showExperiments = inStorybook() || inStorybookTestRunner() ? true : useToolbarFeatureFlag('web-experiments')
|
||||
const showExperimentsFlag = useToolbarFeatureFlag('web-experiments')
|
||||
const showExperiments = inStorybook() || inStorybookTestRunner() ? true : showExperimentsFlag
|
||||
const content = minimized ? null : visibleMenu === 'flags' ? (
|
||||
<FlagsToolbarMenu />
|
||||
) : visibleMenu === 'heatmap' ? (
|
||||
@ -153,7 +154,8 @@ export function Toolbar(): JSX.Element | null {
|
||||
const { setVisibleMenu, toggleMinimized, onMouseOrTouchDown, setElement, setIsBlurred } = useActions(toolbarLogic)
|
||||
const { isAuthenticated, userIntent } = useValues(toolbarConfigLogic)
|
||||
const { authenticate } = useActions(toolbarConfigLogic)
|
||||
const showExperiments = inStorybook() || inStorybookTestRunner() ? true : useToolbarFeatureFlag('web-experiments')
|
||||
const showExperimentsFlag = useToolbarFeatureFlag('web-experiments')
|
||||
const showExperiments = inStorybook() || inStorybookTestRunner() ? true : showExperimentsFlag
|
||||
|
||||
useEffect(() => {
|
||||
setElement(ref.current)
|
||||
|
Loading…
Reference in New Issue
Block a user