Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion js/app/packages/app/component/Launcher.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { analytics } from '@app/lib/analytics';
import { useFeatureFlag } from '@app/lib/analytics/posthog';
import { setAutomationComposerOpen } from '@block-automation/component';
import { setAutomationComposerOpen } from '@block-automation/component/automationComposerState';
import type { BlockAlias, BlockName } from '@core/block';
import { getIconConfig } from '@core/component/EntityIcon';
import {
Expand Down
32 changes: 28 additions & 4 deletions js/app/packages/app/component/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
} from '@app/component/sidebarVisibility';
import { ROUTER_BASE_CONCAT } from '@app/constants/routerBase';
import { mountGlobalFocusListener } from '@app/signal/focus';
import { AutomationComposer } from '@block-automation/component';
import { automationComposerOpen } from '@block-automation/component/automationComposerState';
import { useIsAuthenticated } from '@core/auth';
import { usePaywallState } from '@core/constant/PaywallState';
import { isMobile } from '@core/mobile/isMobile';
import { virtualKeyboardVisible } from '@core/mobile/virtualKeyboard';
import { updateCookie } from '@core/util/cookies';
import { getPlatform } from '@core/util/platform';
import { makePersisted } from '@solid-primitives/storage';
import { type RouteSectionProps, useLocation } from '@solidjs/router';
import { cn, Layer } from '@ui';
Expand All @@ -23,6 +24,7 @@ import {
createEffect,
createMemo,
createSignal,
lazy,
onMount,
Show,
Suspense,
Expand All @@ -37,7 +39,6 @@ import GlobalShortcuts from './GlobalHotkeys';
import { GmailReauthenticationPrompt } from './GmailReauthenticationPrompt';
import { GlobalShareModal } from './global-share-modal/GlobalShareModal';
import { ItemDndProvider } from './ItemDragAndDrop';
import { IosShareSheet } from './ios-share-sheet/IosShareSheet';
import { createMenuOpen, Launcher, setCreateMenuOpen } from './Launcher';
import { MacroMcpSetupModal } from './macro-mcp-setup-modal/MacroMcpSetupModal';
import { MobileDock } from './mobile/MobileDock';
Expand All @@ -47,6 +48,23 @@ import { Paywall } from './paywall/Paywall';
import { PropertyEditorModal } from './property-edit-modal/PropertyEditorModal';
import { useAppSquishHandlers } from './useAppSquishHandlers';

// Lazy + iOS-gated: the share sheet pulls in the channel input / markdown
// editor stack, which would otherwise load with the initial bundle on every
// platform.
// Lazy + open-gated: the composer pulls in the markdown editor stack. The
// chunk loads the first time the composer is opened.
const AutomationComposer = lazy(() =>
import('@block-automation/component/AutomationComposer').then((m) => ({
default: m.AutomationComposer,
}))
);

const IosShareSheet = lazy(() =>
import('./ios-share-sheet/IosShareSheet').then((m) => ({
default: m.IosShareSheet,
}))
);

const AUTH_URLS = [
`${ROUTER_BASE_CONCAT}login`,
`${ROUTER_BASE_CONCAT}login/popup`,
Expand Down Expand Up @@ -153,7 +171,9 @@ function LayoutInner(props: RouteSectionProps) {
</Suspense>
<GlobalBulkEditEntityModal />
<GlobalShareModal />
<IosShareSheet />
<Show when={getPlatform() === 'ios'}>
<IosShareSheet />
</Show>
Comment on lines +174 to +176

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify where IosShareSheet is mounted relative to Suspense boundaries.
rg -n -C3 "IosShareSheet|<Suspense>|</Suspense>" js/app/packages/app/component/Layout.tsx

Repository: macro-inc/macro

Length of output: 1847


🏁 Script executed:

#!/bin/bash
# Inspect surrounding Suspense boundaries and the IosShareSheet render location
nl -ba js/app/packages/app/component/Layout.tsx | sed -n '140,200p'

Repository: macro-inc/macro

Length of output: 100


🏁 Script executed:

#!/bin/bash
# Show Layout.tsx section around the Suspense boundaries and IosShareSheet
sed -n '130,200p' js/app/packages/app/component/Layout.tsx

Repository: macro-inc/macro

Length of output: 2095


🏁 Script executed:

#!/bin/bash
# Find all Suspense usages (and whether they specify a fallback) in this file
rg -n "<Suspense" js/app/packages/app/component/Layout.tsx

Repository: macro-inc/macro

Length of output: 180


Wrap IosShareSheet in a local <Suspense> boundary.

IosShareSheet is a lazy component rendered directly under the outer <Suspense> (no local boundary), so its first unresolved load can suspend the rest of the authenticated subtree. Isolate it like the existing AutomationComposer pattern.

Proposed fix
-          <Show when={getPlatform() === 'ios'}>
-            <IosShareSheet />
-          </Show>
+          <Show when={getPlatform() === 'ios'}>
+            <Suspense>
+              <IosShareSheet />
+            </Suspense>
+          </Show>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Show when={getPlatform() === 'ios'}>
<IosShareSheet />
</Show>
<Show when={getPlatform() === 'ios'}>
<Suspense>
<IosShareSheet />
</Suspense>
</Show>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/app/component/Layout.tsx` around lines 174 - 176, The
IosShareSheet lazy component is rendered directly under the outer Suspense and
can suspend the whole authenticated subtree; wrap the IosShareSheet component in
a local Suspense boundary (similar to the AutomationComposer pattern) so its
loading only affects itself. Locate the Show block using getPlatform() === 'ios'
and replace the direct <IosShareSheet /> with a local <Suspense fallback={null}>
(or appropriate minimal fallback) that contains <IosShareSheet /> to isolate its
suspension.

<MacroMcpSetupModal />
</Show>
<Show
Expand Down Expand Up @@ -212,7 +232,11 @@ function LayoutInner(props: RouteSectionProps) {
when={isAuthenticated() && !AUTH_URLS.includes(location.pathname)}
>
<Launcher open={createMenuOpen()} onOpenChange={setCreateMenuOpen} />
<AutomationComposer />
<Show when={automationComposerOpen()}>
<Suspense>
<AutomationComposer />
</Suspense>
</Show>
</Show>
</Suspense>
<DevStatusBar />
Expand Down
2 changes: 1 addition & 1 deletion js/app/packages/app/component/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { ROUTER_BASE } from '@app/constants/routerBase';
import { PosthogProvider, usePosthog } from '@app/lib/analytics/posthog';
import { setHotkeyRoot } from '@app/signal/hotkeyRoot';
import { globalSplitManager } from '@app/signal/splitLayout';
import { CallKitSync } from '@channel/Call';
import { CallProvider } from '@channel/Call/CallContext';
import { CallStartedNotifier } from '@channel/Call/CallStartedNotifier';
import { CallKitSync } from '@channel/Call/use-callkit';
import { ChatAttachmentsInit } from '@core/component/AI/signal/globalAttachments';
import { toast } from '@core/component/Toast/Toast';
import { ToastRegion } from '@core/component/Toast/ToastRegion';
Expand Down
10 changes: 4 additions & 6 deletions js/app/packages/app/component/app-sidebar/active-call-widget.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {
joinChannelCall,
openChannelCallTab,
stopCallRinger,
useCallContextOptional,
} from '@channel/Call';
import { useCallContextOptional } from '@channel/Call/CallContext';
import { stopCallRinger } from '@channel/Call/CallStartedNotifier';
import { joinChannelCall } from '@channel/Call/join-channel-call';
import { openChannelCallTab } from '@channel/Call/open-channel-call-tab';
import { ContextMenuContent, MenuItem } from '@core/component/ContextMenu';
import { ENABLE_CALLS } from '@core/constant/featureFlags';
import { useChannelsContext } from '@core/context/channels';
Expand Down
2 changes: 1 addition & 1 deletion js/app/packages/app/component/app-sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import {
import { useFeatureFlag } from '@app/lib/analytics/posthog';
import { useHotkeyInterceptor } from '@app/signal/hotkeyRoot';
import { globalSplitManager } from '@app/signal/splitLayout';
import { InCallPanel } from '@channel/Call';
import { useCallContextOptional } from '@channel/Call/CallContext';
import { InCallPanel } from '@channel/Call/InCallPanel';
import { useHasPaidAccess } from '@core/auth';
import { ContextMenuContent, MenuItem } from '@core/component/ContextMenu';
import { inboxIconProps } from '@core/component/inboxIcon';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import type { BlockAlias, BlockName } from '@core/block';
import { Permissions } from '@core/component/SharePermissions';
import { ShareModal } from '@core/component/TopBar/ShareButton';
import { itemToBlockName } from '@core/constant/allBlocks';
import { createControlledOpenSignal } from '@core/util/createControlledOpenSignal';
import type { EntityData } from '@entity';
import type { ItemType } from '@service-storage/client';
import { createSignal, Show } from 'solid-js';
import { createSignal, lazy, Show, Suspense } from 'solid-js';

// Lazy + open-gated: ShareModal pulls in ForwardToChannel and the markdown
// editor stack, which would otherwise load with the initial bundle.
const ShareModal = lazy(() =>
import('@core/component/TopBar/ShareButton').then((m) => ({
default: m.ShareModal,
}))
);

type ShareableEntityType = 'document' | 'chat' | 'project';

Expand Down Expand Up @@ -76,16 +83,18 @@ export const GlobalShareModal = () => {
const entity = () => propsAccessor().entity;

return (
<ShareModal
isSharePermOpen={modalOpen()}
setIsSharePermOpen={handleSetIsOpen}
id={entity().id}
blockAlias={getEntityBlockAlias(entity())}
itemType={getEntityItemType(entity())}
name={entity().name}
userPermissions={Permissions.OWNER}
owner={entity().ownerId}
/>
<Suspense>
<ShareModal
isSharePermOpen={modalOpen()}
setIsSharePermOpen={handleSetIsOpen}
id={entity().id}
blockAlias={getEntityBlockAlias(entity())}
itemType={getEntityItemType(entity())}
name={entity().name}
userPermissions={Permissions.OWNER}
owner={entity().ownerId}
/>
</Suspense>
);
}}
</Show>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@ import ArrowRightIcon from '@phosphor/arrow-right.svg';
import CloseIcon from '@phosphor/x.svg';
import { useCompleteTutorialMutation } from '@queries/auth/tutorial';
import { Button, Dialog, Hotkey } from '@ui';
import { type Component, createSignal, Match, Show, Switch } from 'solid-js';
import {
type Component,
createSignal,
lazy,
Match,
Show,
Suspense,
Switch,
} from 'solid-js';
import { Dynamic } from 'solid-js/web';
import InteractiveOnboarding from './InteractiveOnboarding';
import { OnboardingProgress } from './OnboardingProgress';
import { useOnboarding } from './onboarding-context';
import type { LessonContentProps, LessonState } from './types';

// Lazy: the onboarding lessons pull in the markdown editor stack (mentions,
// emoji search, etc.), which would otherwise load with the initial bundle.
// The chunk is fetched the first time the modal actually opens.
const InteractiveOnboarding = lazy(() => import('./InteractiveOnboarding'));

interface InteractiveOnboardingModalProps {
open?: boolean;
defaultOpen?: boolean;
Expand Down Expand Up @@ -318,16 +330,19 @@ export function InteractiveOnboardingModal(
>
<div class="relative size-full overflow-hidden rounded-xl flex flex-col">
<Show when={open()}>
<InteractiveOnboarding
onDismiss={() => setOpen(false)}
ignoreTutorialCompleted
isFirstTimeOnboarding={props.isFirstTimeOnboarding}
>
<InteractiveOnboardingModalLayout
isFirstTimeOnboarding={props.isFirstTimeOnboarding === true}
onClose={() => setOpen(false)}
/>
</InteractiveOnboarding>
{/* Local boundary so the lazy chunk load can't re-trigger an outer Suspense. */}
<Suspense>
<InteractiveOnboarding
onDismiss={() => setOpen(false)}
ignoreTutorialCompleted
isFirstTimeOnboarding={props.isFirstTimeOnboarding}
>
<InteractiveOnboardingModalLayout
isFirstTimeOnboarding={props.isFirstTimeOnboarding === true}
onClose={() => setOpen(false)}
/>
</InteractiveOnboarding>
</Suspense>
</Show>
</div>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MobileDrawer } from '@app/component/mobile/MobileDrawer';
import { useSplitPanelOrThrow } from '@app/component/split-layout/layoutUtils';
import { getShareDrawerRecipientInput } from '@core/component/TopBar/ShareButton';
import { getShareDrawerRecipientInput } from '@core/component/TopBar/shareDrawer';
import { triggerFocusInput } from '@core/directive/focusInput';
import { InlineEntity } from '@entity';
import { cn } from '@ui';
Expand Down
2 changes: 1 addition & 1 deletion js/app/packages/app/component/next-soup/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { URL_PARAMS as CHANNEL_PARAMS } from '@block-channel/constants';
import { getChannelParams } from '@block-channel/utils/link';
import { URL_PARAMS as EMAIL_PARAMS } from '@block-email/constants';
import { URL_PARAMS as MD_PARAMS } from '@block-md/constants';
import { URL_PARAMS as PDF_PARAMS } from '@block-pdf/signal/location';
import { URL_PARAMS as PDF_PARAMS } from '@block-pdf/constants';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Canonical PDF URL param definitions =="
rg -n --type=ts --type=tsx -C2 "pdf_search_page|pdf_search_raw_query|pdf_search_highlight_terms|pdf_search_snippet|URL_PARAMS\\.searchPage|URL_PARAMS\\.searchRawQuery|URL_PARAMS\\.searchHighlightTerms|URL_PARAMS\\.searchSnippet"

echo
echo "== Legacy literal key usage =="
rg -n --type=ts --type=tsx -C2 "'search_page'|\"search_page\"|'search_raw_query'|\"search_raw_query\"|'search_highlight_terms'|\"search_highlight_terms\"|'search_snippet'|\"search_snippet\""

echo
echo "== URL parsing/normalization sites for PDF params =="
rg -n --type=ts --type=tsx -C3 "parseLocationFromUrl|parseLocationFromBlockParams|goToLocationFromParams|URLSearchParams|get\\(.*search_page|get\\(.*pdf_search_page"

Repository: macro-inc/macro

Length of output: 147


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Canonical PDF URL param definitions (PDF_PARAMS / URL_PARAMS members) =="
rg -n -g'*.ts' -g'*.tsx' -C2 \
  "PDF_PARAMS|URL_PARAMS\\.(searchPage|searchRawQuery|searchHighlightTerms|searchSnippet)" \
  js/app || true

echo
echo "== Legacy literal key usage (search_page / raw_query / highlight_terms / snippet) =="
rg -n -g'*.ts' -g'*.tsx' -C3 \
  "['\"]search_page['\"]|['\"]search_raw_query['\"]|['\"]search_highlight_terms['\"]|['\"]search_snippet['\"]" \
  js/app || true

echo
echo "== Usage of pdf_search_* keys =="
rg -n -g'*.ts' -g'*.tsx' -C2 \
  "pdf_search_page|pdf_search_raw_query|pdf_search_highlight_terms|pdf_search_snippet" \
  js/app || true

echo
echo "== URL parsing/normalization sites for PDF params =="
rg -n -g'*.ts' -g'*.tsx' -C3 \
  "(parseLocationFromUrl|parseLocationFromBlockParams|goToLocationFromParams|URLSearchParams|get\\(.*search_page|get\\(.*pdf_search_page))" \
  js/app || true

echo
echo "== Focus: utils.ts functions around openEntityInNewTab / navigateToLocation =="
FILE="js/app/packages/app/component/next-soup/utils.ts"
if [ -f "$FILE" ]; then
  rg -n -g'*.ts' -g'*.tsx' "openEntityInNewTab|navigateToLocation" "$FILE" || true
  echo "--- openEntityInNewTab context ---"
  rg -n -g'*.ts' -g'*.tsx' "openEntityInNewTab" "$FILE" -C12 || true
  echo "--- navigateToLocation context ---"
  rg -n -g'*.ts' -g'*.tsx' "navigateToLocation" "$FILE" -C12 || true
else
  echo "Missing file: $FILE" >&2
  exit 1
fi

Repository: macro-inc/macro

Length of output: 9124


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Where legacy keys are used across the repo =="
rg -n -g'*.ts' -g'*.tsx' \
  "['\"]search_page['\"]|['\"]search_raw_query['\"]|['\"]search_highlight_terms['\"]|['\"]search_snippet['\"]" \
  js/app | head -n 200

echo
echo "== Where canonical pdf_search_* keys are referenced =="
rg -n -g'*.ts' -g'*.tsx' \
  "pdf_search_page|pdf_search_raw_query|pdf_search_highlight_terms|pdf_search_snippet" \
  js/app | head -n 200

echo
echo "== Any normalization from legacy -> canonical in block-pdf package? =="
rg -n -g'*.ts' -g'*.tsx' \
  "search_page|search_raw_query|search_highlight_terms|search_snippet|pdf_search_page|pdf_search_raw_query|pdf_search_highlight_terms|pdf_search_snippet" \
  js/app/packages/block-pdf | head -n 400

Repository: macro-inc/macro

Length of output: 1297


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) next-soup/utils.ts around openEntityInNewTab pdf block
FILE1="js/app/packages/app/component/next-soup/utils.ts"
echo "=== openEntityInNewTab PDF block (utils.ts) ==="
sed -n '190,270p' "$FILE1" | cat -n

echo
echo "=== navigateToLocation PDF block (utils.ts) ==="
sed -n '430,490p' "$FILE1" | cat -n

# 2) block-pdf constants and parsing
FILE2="js/app/packages/block-pdf/constants.ts"
echo
echo "=== block-pdf/constants.ts (URL_PARAMS) ==="
sed -n '1,120p' "$FILE2" | cat -n

FILE3="js/app/packages/block-pdf/component/Document.tsx"
echo
echo "=== block-pdf/Document.tsx query param reads ==="
# Find the exact searchParams usage region
rg -n "searchParams\\[URL_PARAMS" "$FILE3" | head -n 20
sed -n '500,580p' "$FILE3" | cat -n

FILE4="js/app/packages/block-pdf/signal/location.ts"
echo
echo "=== block-pdf/signal/location.ts parseLocationParams mapping ==="
rg -n "parseLocationParams\\(|URL_PARAMS\\." "$FILE4" | head -n 50
sed -n '360,460p' "$FILE4" | cat -n

# 3) Search for any legacy -> canonical fallback in block-pdf
echo
echo "=== block-pdf legacy key fallback checks ==="
rg -n -g'*.ts' -g'*.tsx' "search_page|search_raw_query|search_highlight_terms|search_snippet" js/app/packages/block-pdf || true

# 4) Rerun URL parsing helper location search (use simpler regex, avoid capturing group mistakes)
echo
echo "=== find URL parsing helpers mentioning search_page/pdf_search_page ==="
rg -n -g'*.ts' -g'*.tsx' "pdf_search_page|search_page" js/app/packages/block-pdf | head -n 100

Repository: macro-inc/macro

Length of output: 15019


Fix PDF new-tab deep links to use canonical pdf_search_* query param keys.

openEntityInNewTab (pdf case) sets legacy keys (search_page, search_raw_query, search_highlight_terms, search_snippet), but navigateToLocation uses PDF_PARAMS.* (pdf_search_*), and block-pdf’s URL parsing (Document.tsx/parseLocationFromUrl) reads only URL_PARAMS.*. This mismatch will silently drop the target location in new-tab PDF links (no legacy fallback in block-pdf).

Update openEntityInNewTab to set entityUrl.searchParams using PDF_PARAMS.searchPage/searchRawQuery/searchHighlightTerms/searchSnippet instead of the hardcoded legacy strings. (js/app/packages/app/component/next-soup/utils.ts, openEntityInNewTab pdf case ~222-243)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app/packages/app/component/next-soup/utils.ts` at line 12,
openEntityInNewTab currently writes legacy PDF query keys (search_page,
search_raw_query, search_highlight_terms, search_snippet) when building PDF
new-tab URLs, but navigateToLocation and block-pdf expect canonical PDF_PARAMS
keys (pdf_search_page, pdf_search_raw_query, pdf_search_highlight_terms,
pdf_search_snippet). Fix openEntityInNewTab (pdf case) to set
entityUrl.searchParams using PDF_PARAMS.searchPage, PDF_PARAMS.searchRawQuery,
PDF_PARAMS.searchHighlightTerms and PDF_PARAMS.searchSnippet instead of the
hardcoded legacy strings so the created URL matches parseLocationFromUrl and
navigateToLocation.

import { fileTypeToBlockName } from '@core/constant/allBlocks';
import {
ENTITY_ID_DATA_ATTRIBUTE,
Expand Down
31 changes: 26 additions & 5 deletions js/app/packages/app/component/split-layout/componentRegistry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { Home } from '@app/component/home';
import type { SetPredicatesInput } from '@app/component/next-soup/filters/filter-store/predicates-store';
import type { Query } from '@app/component/next-soup/filters/filter-store/types';
import { SoupView } from '@app/component/next-soup/soup-view/soup-view';
import { ChannelCompose } from '@block-channel/component/Compose';
import { ComposeTask } from '@block-md/component/ComposeTask';
import { useIsAuthenticated } from '@core/auth';
import { LoadingBlock } from '@core/component/LoadingBlock';
import {
Expand All @@ -17,8 +15,6 @@ import { useUserContext } from '@core/context/user';
import type { ViewId } from '@core/types/view';
import { useAutomationEntities } from '@queries/agent-schedule/entities';
import { type Component, type JSXElement, lazy, onMount, Show } from 'solid-js';
import { EmailCompose } from '../../../block-email/component/compose/Compose';
import { SettingsPanelComponentWrapper } from '../settings/Settings';
import type { SplitContent } from './layoutManager';
import { useSplitPanelOrThrow } from './layoutUtils';

Expand Down Expand Up @@ -311,6 +307,24 @@ registerComponent(
);
/** END - APP ROUTES */

// Lazy: the compose surfaces pull in the markdown/channel editor stacks,
// which would otherwise load with the initial bundle.
const ChannelCompose = lazy(() =>
import('@block-channel/component/Compose').then((m) => ({
default: m.ChannelCompose,
}))
);
const EmailCompose = lazy(() =>
import('../../../block-email/component/compose/Compose').then((m) => ({
default: m.EmailCompose,
}))
);
const ComposeTask = lazy(() =>
import('@block-md/component/ComposeTask').then((m) => ({
default: m.ComposeTask,
}))
);

registerComponent('loading', () => <LoadingBlock />);
registerComponent('channel-compose', () => {
usePageViewTracking('channel-compose');
Expand All @@ -328,7 +342,14 @@ registerComponent(
'import-linear',
lazy(() => import('@app/component/import-linear/ImportLinear'))
);
registerComponent('settings', () => <SettingsPanelComponentWrapper />);
registerComponent(
'settings',
lazy(() =>
import('../settings/Settings').then((m) => ({
default: m.SettingsPanelComponentWrapper,
}))
)
);

if (LOCAL_ONLY) {
registerComponent(
Expand Down
Loading
Loading