mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-10-16 01:51:30 +08:00

* feat(organization): add hname and alias for organization * fix: boolean values are not shown in the list panel's column * fix: moved logic to component level * fix: added type * fix: added test cases * fix: added test cases * chore: update copy webpack plugin * Revert "fix: display same key with multiple data types in filter suggestions by enhancing the deduping logic (#7255)" This reverts commit 1e85981a17a8e715e948308d3e85072d976907d3. * fix: use query search v2 for traces data source to handle multiple data types for the same key * fix(QueryBuilderSearchV2): add user typed option if it doesn't exist in the payload * fix(QueryBuilderSearchV2): increase the height of search dropdown for non-logs data sources * fix: display span scope selector for trace data source * chore: remove the span scope selector from qb search v1 and move the component to search v2 * fix: write test to ensure that we display span scope selector for traces data source * fix: limit converting -> only to log data source * fix: don't display empty suggestion if only spaces are typed * chore: tests for span scope selector * chore: qb search flow (key, operator, value) test cases * refactor: fix the Maximum update depth reached issue while running tests * chore: overall improvements to span scope selector tests Resource attr filter: style fix and quick filter changes (#7691) * chore: resource attr filter init * chore: resource attr filter api integration * chore: operator config updated * chore: fliter show hide logic and styles * chore: add support for custom operator list to qb * chore: minor refactor * chore: minor code refactor * test: quick filters test suite added * test: quick filters test suite added * test: all errors test suite added * chore: style fix * test: all errors mock fix * chore: test case fix and mixpanel update * chore: color update * chore: minor refactor * chore: style fix * chore: set default query in exceptions tab * chore: style fix * chore: minor refactor * chore: minor refactor * chore: minor refactor * chore: test update * chore: fix filter header with no query name * fix: scroll fix * chore: add data source traces to quick filters * chore: replace div with fragment --------- Co-authored-by: Aditya Singh <adityasingh@Adityas-MacBook-Pro.local> fix: handle rate operators for table panel (#7695) * fix: handle rate operators for table panel chore: fix error rate (#7701) Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat(organization): minor cleanups * feat(organization): better naming for api and usecase * feat(organization): better packaging for modules * feat(organization): change hname to displayName * feat(organization): update the migration to use dialect * feat(organization): update the migration to use dialect * feat(organization): update the migration to use dialect * feat(organization): revert back to impl * feat(organization): remove DI from organization * feat(organization): address review comments * feat(organization): address review comments * feat(organization): address review comments --------- Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
287 lines
7.9 KiB
TypeScript
287 lines
7.9 KiB
TypeScript
import './OnboardingQuestionaire.styles.scss';
|
|
|
|
import { NotificationInstance } from 'antd/es/notification/interface';
|
|
import logEvent from 'api/common/logEvent';
|
|
import updateProfileAPI from 'api/onboarding/updateProfile';
|
|
import getAllOrgPreferences from 'api/preferences/getAllOrgPreferences';
|
|
import updateOrgPreferenceAPI from 'api/preferences/updateOrgPreference';
|
|
import { AxiosError } from 'axios';
|
|
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
|
import { FeatureKeys } from 'constants/features';
|
|
import ROUTES from 'constants/routes';
|
|
import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer';
|
|
import { useNotifications } from 'hooks/useNotifications';
|
|
import history from 'lib/history';
|
|
import { useAppContext } from 'providers/App/App';
|
|
import { useEffect, useState } from 'react';
|
|
import { useMutation, useQuery } from 'react-query';
|
|
|
|
import {
|
|
AboutSigNozQuestions,
|
|
SignozDetails,
|
|
} from './AboutSigNozQuestions/AboutSigNozQuestions';
|
|
import InviteTeamMembers from './InviteTeamMembers/InviteTeamMembers';
|
|
import { OnboardingHeader } from './OnboardingHeader/OnboardingHeader';
|
|
import OptimiseSignozNeeds, {
|
|
OptimiseSignozDetails,
|
|
} from './OptimiseSignozNeeds/OptimiseSignozNeeds';
|
|
import OrgQuestions, { OrgData, OrgDetails } from './OrgQuestions/OrgQuestions';
|
|
|
|
export const showErrorNotification = (
|
|
notifications: NotificationInstance,
|
|
err: Error,
|
|
): void => {
|
|
notifications.error({
|
|
message: err.message || SOMETHING_WENT_WRONG,
|
|
});
|
|
};
|
|
|
|
const INITIAL_ORG_DETAILS: OrgDetails = {
|
|
organisationName: '',
|
|
usesObservability: true,
|
|
observabilityTool: '',
|
|
otherTool: '',
|
|
familiarity: '',
|
|
};
|
|
|
|
const INITIAL_SIGNOZ_DETAILS: SignozDetails = {
|
|
hearAboutSignoz: '',
|
|
interestInSignoz: '',
|
|
otherInterestInSignoz: '',
|
|
otherAboutSignoz: '',
|
|
};
|
|
|
|
const INITIAL_OPTIMISE_SIGNOZ_DETAILS: OptimiseSignozDetails = {
|
|
logsPerDay: 0,
|
|
hostsPerDay: 0,
|
|
services: 0,
|
|
};
|
|
|
|
const BACK_BUTTON_EVENT_NAME = 'Org Onboarding: Back Button Clicked';
|
|
const NEXT_BUTTON_EVENT_NAME = 'Org Onboarding: Next Button Clicked';
|
|
const ONBOARDING_COMPLETE_EVENT_NAME = 'Org Onboarding: Complete';
|
|
|
|
function OnboardingQuestionaire(): JSX.Element {
|
|
const { notifications } = useNotifications();
|
|
const { org, updateOrgPreferences, featureFlags } = useAppContext();
|
|
const isOnboardingV3Enabled = featureFlags?.find(
|
|
(flag) => flag.name === FeatureKeys.ONBOARDING_V3,
|
|
)?.active;
|
|
const [currentStep, setCurrentStep] = useState<number>(1);
|
|
const [orgDetails, setOrgDetails] = useState<OrgDetails>(INITIAL_ORG_DETAILS);
|
|
const [signozDetails, setSignozDetails] = useState<SignozDetails>(
|
|
INITIAL_SIGNOZ_DETAILS,
|
|
);
|
|
|
|
const [
|
|
optimiseSignozDetails,
|
|
setOptimiseSignozDetails,
|
|
] = useState<OptimiseSignozDetails>(INITIAL_OPTIMISE_SIGNOZ_DETAILS);
|
|
const [teamMembers, setTeamMembers] = useState<
|
|
InviteTeamMembersProps[] | null
|
|
>(null);
|
|
|
|
const [currentOrgData, setCurrentOrgData] = useState<OrgData | null>(null);
|
|
|
|
const [
|
|
updatingOrgOnboardingStatus,
|
|
setUpdatingOrgOnboardingStatus,
|
|
] = useState<boolean>(false);
|
|
|
|
useEffect(() => {
|
|
if (org) {
|
|
setCurrentOrgData(org[0]);
|
|
|
|
setOrgDetails({
|
|
...orgDetails,
|
|
organisationName: org[0].displayName,
|
|
});
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [org]);
|
|
|
|
useEffect(() => {
|
|
logEvent('Org Onboarding: Started', {
|
|
org_id: org?.[0]?.id,
|
|
});
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
const { refetch: refetchOrgPreferences } = useQuery({
|
|
queryFn: () => getAllOrgPreferences(),
|
|
queryKey: ['getOrgPreferences'],
|
|
enabled: false,
|
|
refetchOnWindowFocus: false,
|
|
onSuccess: (response) => {
|
|
if (response.payload && response.payload.data) {
|
|
updateOrgPreferences(response.payload.data);
|
|
}
|
|
|
|
setUpdatingOrgOnboardingStatus(false);
|
|
|
|
logEvent('Org Onboarding: Redirecting to Get Started', {});
|
|
|
|
if (isOnboardingV3Enabled) {
|
|
history.push(ROUTES.GET_STARTED_WITH_CLOUD);
|
|
} else {
|
|
history.push(ROUTES.GET_STARTED);
|
|
}
|
|
},
|
|
onError: () => {
|
|
setUpdatingOrgOnboardingStatus(false);
|
|
},
|
|
});
|
|
|
|
const isNextDisabled =
|
|
optimiseSignozDetails.logsPerDay === 0 &&
|
|
optimiseSignozDetails.hostsPerDay === 0 &&
|
|
optimiseSignozDetails.services === 0;
|
|
|
|
const { mutate: updateProfile, isLoading: isUpdatingProfile } = useMutation(
|
|
updateProfileAPI,
|
|
{
|
|
onSuccess: () => {
|
|
setCurrentStep(4);
|
|
},
|
|
onError: (error) => {
|
|
showErrorNotification(notifications, error as AxiosError);
|
|
},
|
|
},
|
|
);
|
|
|
|
const { mutate: updateOrgPreference } = useMutation(updateOrgPreferenceAPI, {
|
|
onSuccess: () => {
|
|
refetchOrgPreferences();
|
|
},
|
|
onError: (error) => {
|
|
showErrorNotification(notifications, error as AxiosError);
|
|
|
|
setUpdatingOrgOnboardingStatus(false);
|
|
},
|
|
});
|
|
|
|
const handleUpdateProfile = (): void => {
|
|
logEvent(NEXT_BUTTON_EVENT_NAME, {
|
|
currentPageID: 3,
|
|
nextPageID: 4,
|
|
});
|
|
|
|
updateProfile({
|
|
familiarity_with_observability: orgDetails?.familiarity as string,
|
|
has_existing_observability_tool: orgDetails?.usesObservability as boolean,
|
|
existing_observability_tool:
|
|
orgDetails?.observabilityTool === 'Others'
|
|
? (orgDetails?.otherTool as string)
|
|
: (orgDetails?.observabilityTool as string),
|
|
|
|
reasons_for_interest_in_signoz:
|
|
signozDetails?.interestInSignoz === 'Others'
|
|
? (signozDetails?.otherInterestInSignoz as string)
|
|
: (signozDetails?.interestInSignoz as string),
|
|
where_did_you_hear_about_signoz:
|
|
signozDetails?.hearAboutSignoz === 'Others'
|
|
? (signozDetails?.otherAboutSignoz as string)
|
|
: (signozDetails?.hearAboutSignoz as string),
|
|
|
|
logs_scale_per_day_in_gb: optimiseSignozDetails?.logsPerDay as number,
|
|
number_of_hosts: optimiseSignozDetails?.hostsPerDay as number,
|
|
number_of_services: optimiseSignozDetails?.services as number,
|
|
});
|
|
};
|
|
|
|
const handleOnboardingComplete = (): void => {
|
|
logEvent(ONBOARDING_COMPLETE_EVENT_NAME, {
|
|
currentPageID: 4,
|
|
});
|
|
|
|
setUpdatingOrgOnboardingStatus(true);
|
|
updateOrgPreference({
|
|
preferenceID: 'ORG_ONBOARDING',
|
|
value: true,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="onboarding-questionaire-container">
|
|
<div className="onboarding-questionaire-header">
|
|
<OnboardingHeader />
|
|
</div>
|
|
|
|
<div className="onboarding-questionaire-content">
|
|
{currentStep === 1 && (
|
|
<OrgQuestions
|
|
currentOrgData={currentOrgData}
|
|
orgDetails={orgDetails}
|
|
onNext={(orgDetails: OrgDetails): void => {
|
|
logEvent(NEXT_BUTTON_EVENT_NAME, {
|
|
currentPageID: 1,
|
|
nextPageID: 2,
|
|
});
|
|
|
|
setOrgDetails(orgDetails);
|
|
setCurrentStep(2);
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 2 && (
|
|
<AboutSigNozQuestions
|
|
signozDetails={signozDetails}
|
|
setSignozDetails={setSignozDetails}
|
|
onBack={(): void => {
|
|
logEvent(BACK_BUTTON_EVENT_NAME, {
|
|
currentPageID: 2,
|
|
prevPageID: 1,
|
|
});
|
|
setCurrentStep(1);
|
|
}}
|
|
onNext={(): void => {
|
|
logEvent(NEXT_BUTTON_EVENT_NAME, {
|
|
currentPageID: 2,
|
|
nextPageID: 3,
|
|
});
|
|
setCurrentStep(3);
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 3 && (
|
|
<OptimiseSignozNeeds
|
|
isNextDisabled={isNextDisabled}
|
|
isUpdatingProfile={isUpdatingProfile}
|
|
optimiseSignozDetails={optimiseSignozDetails}
|
|
setOptimiseSignozDetails={setOptimiseSignozDetails}
|
|
onBack={(): void => {
|
|
logEvent(BACK_BUTTON_EVENT_NAME, {
|
|
currentPageID: 3,
|
|
prevPageID: 2,
|
|
});
|
|
setCurrentStep(2);
|
|
}}
|
|
onNext={handleUpdateProfile}
|
|
onWillDoLater={(): void => setCurrentStep(4)}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 4 && (
|
|
<InviteTeamMembers
|
|
isLoading={updatingOrgOnboardingStatus}
|
|
teamMembers={teamMembers}
|
|
setTeamMembers={setTeamMembers}
|
|
onBack={(): void => {
|
|
logEvent(BACK_BUTTON_EVENT_NAME, {
|
|
currentPageID: 4,
|
|
prevPageID: 3,
|
|
});
|
|
setCurrentStep(3);
|
|
}}
|
|
onNext={handleOnboardingComplete}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default OnboardingQuestionaire;
|