[WEB-2103]: chore: Intercom integration (#5295)
* fix: intecom sdk integration * dev: integrated intercom in god-mode * dev: intercom default value true * dev: updated intercom keys in intercom provider * chore: added restriction values --------- Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
parent
34820eec7a
commit
0619f1b6d1
18 changed files with 221 additions and 40 deletions
|
|
@ -9,6 +9,7 @@ import { IInstance, IInstanceAdmin } from "@plane/types";
|
||||||
import { Button, Input, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
|
import { Button, Input, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { ControllerInput } from "@/components/common";
|
import { ControllerInput } from "@/components/common";
|
||||||
|
import { IntercomConfig } from "./intercom";
|
||||||
// hooks
|
// hooks
|
||||||
import { useInstance } from "@/hooks/store";
|
import { useInstance } from "@/hooks/store";
|
||||||
|
|
||||||
|
|
@ -20,11 +21,13 @@ export interface IGeneralConfigurationForm {
|
||||||
export const GeneralConfigurationForm: FC<IGeneralConfigurationForm> = observer((props) => {
|
export const GeneralConfigurationForm: FC<IGeneralConfigurationForm> = observer((props) => {
|
||||||
const { instance, instanceAdmins } = props;
|
const { instance, instanceAdmins } = props;
|
||||||
// hooks
|
// hooks
|
||||||
const { updateInstanceInfo } = useInstance();
|
const { instanceConfigurations, updateInstanceInfo, updateInstanceConfigurations } = useInstance();
|
||||||
|
|
||||||
// form data
|
// form data
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
|
watch,
|
||||||
formState: { errors, isSubmitting },
|
formState: { errors, isSubmitting },
|
||||||
} = useForm<Partial<IInstance>>({
|
} = useForm<Partial<IInstance>>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
|
@ -36,7 +39,16 @@ export const GeneralConfigurationForm: FC<IGeneralConfigurationForm> = observer(
|
||||||
const onSubmit = async (formData: Partial<IInstance>) => {
|
const onSubmit = async (formData: Partial<IInstance>) => {
|
||||||
const payload: Partial<IInstance> = { ...formData };
|
const payload: Partial<IInstance> = { ...formData };
|
||||||
|
|
||||||
console.log("payload", payload);
|
// update the intercom configuration
|
||||||
|
const isIntercomEnabled =
|
||||||
|
instanceConfigurations?.find((config) => config.key === "IS_INTERCOM_ENABLED")?.value === "1";
|
||||||
|
if (!payload.is_telemetry_enabled && isIntercomEnabled) {
|
||||||
|
try {
|
||||||
|
await updateInstanceConfigurations({ IS_INTERCOM_ENABLED: "0" });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await updateInstanceInfo(payload)
|
await updateInstanceInfo(payload)
|
||||||
.then(() =>
|
.then(() =>
|
||||||
|
|
@ -93,7 +105,8 @@ export const GeneralConfigurationForm: FC<IGeneralConfigurationForm> = observer(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="text-lg font-medium">Telemetry</div>
|
<div className="text-lg font-medium">Chat + telemetry</div>
|
||||||
|
<IntercomConfig isTelemetryEnabled={watch("is_telemetry_enabled") ?? false} />
|
||||||
<div className="flex items-center gap-14 px-4 py-3 border border-custom-border-200 rounded">
|
<div className="flex items-center gap-14 px-4 py-3 border border-custom-border-200 rounded">
|
||||||
<div className="grow flex items-center gap-4">
|
<div className="grow flex items-center gap-4">
|
||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
|
|
|
||||||
82
admin/app/general/intercom.tsx
Normal file
82
admin/app/general/intercom.tsx
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FC, FormEvent, useEffect, useState } from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { MessageSquare } from "lucide-react";
|
||||||
|
import useSWR from "swr";
|
||||||
|
import { IFormattedInstanceConfiguration } from "@plane/types";
|
||||||
|
import { Button, Input, ToggleSwitch } from "@plane/ui";
|
||||||
|
// hooks
|
||||||
|
import { useInstance } from "@/hooks/store";
|
||||||
|
|
||||||
|
type TIntercomConfig = {
|
||||||
|
isTelemetryEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const IntercomConfig: FC<TIntercomConfig> = observer((props) => {
|
||||||
|
const { isTelemetryEnabled } = props;
|
||||||
|
// hooks
|
||||||
|
const { instanceConfigurations, instance, updateInstanceConfigurations, fetchInstanceConfigurations } = useInstance();
|
||||||
|
// states
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||||
|
|
||||||
|
// derived values
|
||||||
|
const isIntercomEnabled = isTelemetryEnabled
|
||||||
|
? instanceConfigurations
|
||||||
|
? instanceConfigurations?.find((config) => config.key === "IS_INTERCOM_ENABLED")?.value === "1"
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
: undefined
|
||||||
|
: false;
|
||||||
|
|
||||||
|
const { isLoading } = useSWR(isTelemetryEnabled ? "INSTANCE_CONFIGURATIONS" : null, () =>
|
||||||
|
isTelemetryEnabled ? fetchInstanceConfigurations() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
const initialLoader = isLoading && isIntercomEnabled === undefined;
|
||||||
|
|
||||||
|
const submitInstanceConfigurations = async (payload: Partial<IFormattedInstanceConfiguration>) => {
|
||||||
|
try {
|
||||||
|
await updateInstanceConfigurations(payload);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
setIsSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const enableIntercomConfig = () => {
|
||||||
|
submitInstanceConfigurations({ IS_INTERCOM_ENABLED: isIntercomEnabled ? "0" : "1" });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-14 px-4 py-3 border border-custom-border-200 rounded">
|
||||||
|
<div className="grow flex items-center gap-4">
|
||||||
|
<div className="shrink-0">
|
||||||
|
<div className="flex items-center justify-center w-10 h-10 bg-custom-background-80 rounded-full">
|
||||||
|
<MessageSquare className="w-6 h-6 text-custom-text-300/80 p-0.5" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grow">
|
||||||
|
<div className="text-sm font-medium text-custom-text-100 leading-5">Talk to Plane</div>
|
||||||
|
<div className="text-xs font-normal text-custom-text-300 leading-5">
|
||||||
|
Let your members chat with us via Intercom or another service. Toggling Telemetry off turns this off
|
||||||
|
automatically.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ml-auto">
|
||||||
|
<ToggleSwitch
|
||||||
|
value={isIntercomEnabled ? true : false}
|
||||||
|
onChange={enableIntercomConfig}
|
||||||
|
size="sm"
|
||||||
|
disabled={!isTelemetryEnabled || isSubmitting || initialLoader}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
@ -7,7 +7,7 @@ import { GeneralConfigurationForm } from "./form";
|
||||||
|
|
||||||
function GeneralPage() {
|
function GeneralPage() {
|
||||||
const { instance, instanceAdmins } = useInstance();
|
const { instance, instanceAdmins } = useInstance();
|
||||||
console.log("instance", instance);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="relative container mx-auto w-full h-full p-4 py-4 space-y-6 flex flex-col">
|
<div className="relative container mx-auto w-full h-full p-4 py-4 space-y-6 flex flex-col">
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ export const InstanceSignInForm: FC = (props) => {
|
||||||
const handleFormChange = (key: keyof TFormData, value: string | boolean) =>
|
const handleFormChange = (key: keyof TFormData, value: string | boolean) =>
|
||||||
setFormData((prev) => ({ ...prev, [key]: value }));
|
setFormData((prev) => ({ ...prev, [key]: value }));
|
||||||
|
|
||||||
console.log("csrfToken", csrfToken);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (csrfToken === undefined)
|
if (csrfToken === undefined)
|
||||||
authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
|
authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@ class InstanceEndpoint(BaseAPIView):
|
||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
UNSPLASH_ACCESS_KEY,
|
UNSPLASH_ACCESS_KEY,
|
||||||
OPENAI_API_KEY,
|
OPENAI_API_KEY,
|
||||||
|
IS_INTERCOM_ENABLED,
|
||||||
|
INTERCOM_APP_ID,
|
||||||
) = get_configuration_value(
|
) = get_configuration_value(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
@ -116,6 +118,15 @@ class InstanceEndpoint(BaseAPIView):
|
||||||
"key": "OPENAI_API_KEY",
|
"key": "OPENAI_API_KEY",
|
||||||
"default": os.environ.get("OPENAI_API_KEY", ""),
|
"default": os.environ.get("OPENAI_API_KEY", ""),
|
||||||
},
|
},
|
||||||
|
# Intercom settings
|
||||||
|
{
|
||||||
|
"key": "IS_INTERCOM_ENABLED",
|
||||||
|
"default": os.environ.get("IS_INTERCOM_ENABLED", "1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "INTERCOM_APP_ID",
|
||||||
|
"default": os.environ.get("INTERCOM_APP_ID", ""),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -151,6 +162,10 @@ class InstanceEndpoint(BaseAPIView):
|
||||||
# is smtp configured
|
# is smtp configured
|
||||||
data["is_smtp_configured"] = bool(EMAIL_HOST)
|
data["is_smtp_configured"] = bool(EMAIL_HOST)
|
||||||
|
|
||||||
|
# Intercom settings
|
||||||
|
data["is_intercom_enabled"] = IS_INTERCOM_ENABLED == "1"
|
||||||
|
data["intercom_app_id"] = INTERCOM_APP_ID
|
||||||
|
|
||||||
# Base URL
|
# Base URL
|
||||||
data["admin_base_url"] = settings.ADMIN_BASE_URL
|
data["admin_base_url"] = settings.ADMIN_BASE_URL
|
||||||
data["space_base_url"] = settings.SPACE_BASE_URL
|
data["space_base_url"] = settings.SPACE_BASE_URL
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,19 @@ class Command(BaseCommand):
|
||||||
"category": "UNSPLASH",
|
"category": "UNSPLASH",
|
||||||
"is_encrypted": True,
|
"is_encrypted": True,
|
||||||
},
|
},
|
||||||
|
# intercom settings
|
||||||
|
{
|
||||||
|
"key": "IS_INTERCOM_ENABLED",
|
||||||
|
"value": os.environ.get("IS_INTERCOM_ENABLED", "1"),
|
||||||
|
"category": "INTERCOM",
|
||||||
|
"is_encrypted": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "INTERCOM_APP_ID",
|
||||||
|
"value": os.environ.get("INTERCOM_APP_ID", ""),
|
||||||
|
"category": "INTERCOM",
|
||||||
|
"is_encrypted": False,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
for item in config_keys:
|
for item in config_keys:
|
||||||
|
|
@ -265,7 +278,11 @@ class Command(BaseCommand):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if bool(GITLAB_HOST) and bool(GITLAB_CLIENT_ID) and bool(GITLAB_CLIENT_SECRET):
|
if (
|
||||||
|
bool(GITLAB_HOST)
|
||||||
|
and bool(GITLAB_CLIENT_ID)
|
||||||
|
and bool(GITLAB_CLIENT_SECRET)
|
||||||
|
):
|
||||||
value = "1"
|
value = "1"
|
||||||
else:
|
else:
|
||||||
value = "0"
|
value = "0"
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,9 @@ RESTRICTED_WORKSPACE_SLUGS = [
|
||||||
"channels",
|
"channels",
|
||||||
"upgrade",
|
"upgrade",
|
||||||
"billing",
|
"billing",
|
||||||
|
"sign-in",
|
||||||
|
"sign-up",
|
||||||
|
"signin",
|
||||||
|
"signup",
|
||||||
|
"config",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
10
packages/types/src/instance/base.d.ts
vendored
10
packages/types/src/instance/base.d.ts
vendored
|
|
@ -52,6 +52,9 @@ export interface IInstanceConfig {
|
||||||
app_base_url: string | undefined;
|
app_base_url: string | undefined;
|
||||||
space_base_url: string | undefined;
|
space_base_url: string | undefined;
|
||||||
admin_base_url: string | undefined;
|
admin_base_url: string | undefined;
|
||||||
|
// intercom
|
||||||
|
is_intercom_enabled: boolean;
|
||||||
|
intercom_app_id: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInstanceAdmin {
|
export interface IInstanceAdmin {
|
||||||
|
|
@ -66,11 +69,16 @@ export interface IInstanceAdmin {
|
||||||
user_detail: IUserLite;
|
user_detail: IUserLite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TInstanceIntercomConfigurationKeys =
|
||||||
|
| "IS_INTERCOM_ENABLED"
|
||||||
|
| "INTERCOM_APP_ID";
|
||||||
|
|
||||||
export type TInstanceConfigurationKeys =
|
export type TInstanceConfigurationKeys =
|
||||||
| TInstanceAIConfigurationKeys
|
| TInstanceAIConfigurationKeys
|
||||||
| TInstanceEmailConfigurationKeys
|
| TInstanceEmailConfigurationKeys
|
||||||
| TInstanceImageConfigurationKeys
|
| TInstanceImageConfigurationKeys
|
||||||
| TInstanceAuthenticationKeys;
|
| TInstanceAuthenticationKeys
|
||||||
|
| TInstanceIntercomConfigurationKeys;
|
||||||
|
|
||||||
export interface IInstanceConfiguration {
|
export interface IInstanceConfiguration {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||||
<meta name="apple-mobile-web-app-title" content={SITE_NAME} />
|
<meta name="apple-mobile-web-app-title" content={SITE_NAME} />
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
<link rel="apple-touch-icon" href="/icons/touch-icon-iphone.png" />
|
<link rel="apple-touch-icon" href="/icons/icon-512x512.png" />
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="/icons/icon-152x152.png" />
|
<link rel="apple-touch-icon" sizes="152x152" href="/icons/icon-152x152.png" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180x180.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180x180.png" />
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="/icons/icon-512x512.png" />
|
<link rel="apple-touch-icon" sizes="512x512" href="/icons/icon-512x512.png" />
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { InstanceWrapper } from "@/lib/wrappers";
|
||||||
// dynamic imports
|
// dynamic imports
|
||||||
const StoreWrapper = dynamic(() => import("@/lib/wrappers/store-wrapper"), { ssr: false });
|
const StoreWrapper = dynamic(() => import("@/lib/wrappers/store-wrapper"), { ssr: false });
|
||||||
const PostHogProvider = dynamic(() => import("@/lib/posthog-provider"), { ssr: false });
|
const PostHogProvider = dynamic(() => import("@/lib/posthog-provider"), { ssr: false });
|
||||||
const CrispWrapper = dynamic(() => import("@/lib/wrappers/crisp-wrapper"), { ssr: false });
|
const IntercomProvider = dynamic(() => import("@/lib/intercom-provider"), { ssr: false });
|
||||||
|
|
||||||
export interface IAppProvider {
|
export interface IAppProvider {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|
@ -39,15 +39,15 @@ export const AppProvider: FC<IAppProvider> = (props) => {
|
||||||
<StoreProvider>
|
<StoreProvider>
|
||||||
<ThemeProvider themes={["light", "dark", "light-contrast", "dark-contrast", "custom"]} defaultTheme="system">
|
<ThemeProvider themes={["light", "dark", "light-contrast", "dark-contrast", "custom"]} defaultTheme="system">
|
||||||
<ToastWithTheme />
|
<ToastWithTheme />
|
||||||
<InstanceWrapper>
|
<StoreWrapper>
|
||||||
<StoreWrapper>
|
<InstanceWrapper>
|
||||||
<CrispWrapper>
|
<IntercomProvider>
|
||||||
<PostHogProvider>
|
<PostHogProvider>
|
||||||
<SWRConfig value={SWR_CONFIG}>{children}</SWRConfig>
|
<SWRConfig value={SWR_CONFIG}>{children}</SWRConfig>
|
||||||
</PostHogProvider>
|
</PostHogProvider>
|
||||||
</CrispWrapper>
|
</IntercomProvider>
|
||||||
</StoreWrapper>
|
</InstanceWrapper>
|
||||||
</InstanceWrapper>
|
</StoreWrapper>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</StoreProvider>
|
</StoreProvider>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { DiscordIcon, GithubIcon, Tooltip } from "@plane/ui";
|
||||||
// helpers
|
// helpers
|
||||||
import { cn } from "@/helpers/common.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useAppTheme, useCommandPalette } from "@/hooks/store";
|
import { useAppTheme, useCommandPalette, useInstance } from "@/hooks/store";
|
||||||
import useOutsideClickDetector from "@/hooks/use-outside-click-detector";
|
import useOutsideClickDetector from "@/hooks/use-outside-click-detector";
|
||||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||||
// components
|
// components
|
||||||
|
|
@ -44,6 +44,7 @@ export const SidebarHelpSection: React.FC<WorkspaceHelpSectionProps> = observer(
|
||||||
const { sidebarCollapsed, toggleSidebar } = useAppTheme();
|
const { sidebarCollapsed, toggleSidebar } = useAppTheme();
|
||||||
const { toggleShortcutModal } = useCommandPalette();
|
const { toggleShortcutModal } = useCommandPalette();
|
||||||
const { isMobile } = usePlatformOS();
|
const { isMobile } = usePlatformOS();
|
||||||
|
const { config } = useInstance();
|
||||||
// states
|
// states
|
||||||
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
||||||
// refs
|
// refs
|
||||||
|
|
@ -148,7 +149,7 @@ export const SidebarHelpSection: React.FC<WorkspaceHelpSectionProps> = observer(
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
{process.env.NEXT_PUBLIC_CRISP_ID && (
|
{config?.intercom_app_id && config?.is_intercom_enabled && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleCrispWindowShow}
|
onClick={handleCrispWindowShow}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,32 @@
|
||||||
|
export * from "./estimates";
|
||||||
|
export * from "./notifications";
|
||||||
|
export * from "./pages";
|
||||||
|
export * from "./use-app-theme";
|
||||||
export * from "./use-calendar-view";
|
export * from "./use-calendar-view";
|
||||||
export * from "./use-cycle-filter";
|
export * from "./use-command-palette";
|
||||||
export * from "./use-cycle";
|
export * from "./use-cycle";
|
||||||
export * from "./use-event-tracker";
|
export * from "./use-cycle-filter";
|
||||||
export * from "./use-dashboard";
|
export * from "./use-dashboard";
|
||||||
|
export * from "./use-event-tracker";
|
||||||
export * from "./use-global-view";
|
export * from "./use-global-view";
|
||||||
|
export * from "./use-inbox-issues";
|
||||||
|
export * from "./use-instance";
|
||||||
|
export * from "./use-issue-detail";
|
||||||
|
export * from "./use-issues";
|
||||||
|
export * from "./use-kanban-view";
|
||||||
export * from "./use-label";
|
export * from "./use-label";
|
||||||
export * from "./use-member";
|
export * from "./use-member";
|
||||||
export * from "./use-mention";
|
export * from "./use-mention";
|
||||||
export * from "./use-module";
|
export * from "./use-module";
|
||||||
export * from "./use-multiple-select-store";
|
|
||||||
|
|
||||||
export * from "./pages/use-project-page";
|
|
||||||
export * from "./pages/use-page";
|
|
||||||
|
|
||||||
export * from "./use-module-filter";
|
export * from "./use-module-filter";
|
||||||
|
export * from "./use-multiple-select-store";
|
||||||
|
export * from "./use-project";
|
||||||
export * from "./use-project-filter";
|
export * from "./use-project-filter";
|
||||||
|
export * from "./use-project-inbox";
|
||||||
export * from "./use-project-publish";
|
export * from "./use-project-publish";
|
||||||
export * from "./use-project-state";
|
export * from "./use-project-state";
|
||||||
export * from "./use-project-view";
|
export * from "./use-project-view";
|
||||||
export * from "./use-project";
|
export * from "./use-router-params";
|
||||||
export * from "./use-webhook";
|
export * from "./use-webhook";
|
||||||
export * from "./use-workspace";
|
export * from "./use-workspace";
|
||||||
export * from "./use-issues";
|
|
||||||
export * from "./use-kanban-view";
|
|
||||||
export * from "./use-issue-detail";
|
|
||||||
// project inbox
|
|
||||||
export * from "./use-project-inbox";
|
|
||||||
export * from "./use-inbox-issues";
|
|
||||||
export * from "./user";
|
export * from "./user";
|
||||||
export * from "./use-instance";
|
|
||||||
export * from "./use-app-theme";
|
|
||||||
export * from "./use-command-palette";
|
|
||||||
export * from "./use-router-params";
|
|
||||||
export * from "./estimates";
|
|
||||||
export * from "./notifications";
|
|
||||||
|
|
|
||||||
2
web/core/hooks/store/pages/index.ts
Normal file
2
web/core/hooks/store/pages/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./use-page";
|
||||||
|
export * from "./use-project-page";
|
||||||
33
web/core/lib/intercom-provider.tsx
Normal file
33
web/core/lib/intercom-provider.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { FC, useEffect } from "react";
|
||||||
|
import Intercom from "@intercom/messenger-js-sdk";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
// store hooks
|
||||||
|
import { useUser, useInstance } from "@/hooks/store";
|
||||||
|
|
||||||
|
export type IntercomProviderProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const IntercomProvider: FC<IntercomProviderProps> = observer((props) => {
|
||||||
|
const { children } = props;
|
||||||
|
// hooks
|
||||||
|
const { data: user } = useUser();
|
||||||
|
const { config } = useInstance();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && config?.is_intercom_enabled && config.intercom_app_id) {
|
||||||
|
Intercom({
|
||||||
|
app_id: config.intercom_app_id || "",
|
||||||
|
user_id: user.id,
|
||||||
|
name: `${user.first_name} ${user.last_name}`,
|
||||||
|
email: user.email,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [user, config]);
|
||||||
|
|
||||||
|
return <>{children}</>;
|
||||||
|
});
|
||||||
|
|
||||||
|
export default IntercomProvider;
|
||||||
|
|
@ -46,6 +46,11 @@ const nextConfig = {
|
||||||
destination: "/",
|
destination: "/",
|
||||||
permanent: true,
|
permanent: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
source: "/signin",
|
||||||
|
destination: "/",
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
source: "/register",
|
source: "/register",
|
||||||
destination: "/sign-up",
|
destination: "/sign-up",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
||||||
"@blueprintjs/popover2": "^1.13.3",
|
"@blueprintjs/popover2": "^1.13.3",
|
||||||
"@headlessui/react": "^1.7.3",
|
"@headlessui/react": "^1.7.3",
|
||||||
|
"@intercom/messenger-js-sdk": "^0.0.12",
|
||||||
"@nivo/bar": "0.80.0",
|
"@nivo/bar": "0.80.0",
|
||||||
"@nivo/calendar": "0.80.0",
|
"@nivo/calendar": "0.80.0",
|
||||||
"@nivo/core": "0.80.0",
|
"@nivo/core": "0.80.0",
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"sw.js","sources":["../../../../../private/tmp/50f50ba014f4feaeaa3ddc8366af217e/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}
|
{"version":3,"file":"sw.js","sources":["../../../../../private/tmp/50f50ba014f4feaeaa3ddc8366af217e/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/aaryan610/Desktop/plane/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"}
|
||||||
|
|
|
||||||
|
|
@ -1640,6 +1640,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
||||||
integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==
|
integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==
|
||||||
|
|
||||||
|
"@intercom/messenger-js-sdk@^0.0.12":
|
||||||
|
version "0.0.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@intercom/messenger-js-sdk/-/messenger-js-sdk-0.0.12.tgz#1b80acf6b2a59ef9ce4010e0920522d579a590fa"
|
||||||
|
integrity sha512-xoUGlKLD8nIcZaH7AesR/LfwXH4QQUdPZMV4sApK/zvVFBgAY/A9IWp1ey/jUcp+776ejtZeEqreJZxG4LdEuw==
|
||||||
|
|
||||||
"@isaacs/cliui@^8.0.2":
|
"@isaacs/cliui@^8.0.2":
|
||||||
version "8.0.2"
|
version "8.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
|
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
|
||||||
|
|
@ -4446,7 +4451,7 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48":
|
"@types/react@*", "@types/react@18.2.48", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48":
|
||||||
version "18.2.48"
|
version "18.2.48"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
|
||||||
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==
|
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue