mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): add tracking (#3521)
This commit is contained in:
parent
1f374b87df
commit
ee3135a536
23 changed files with 258 additions and 60 deletions
|
@ -27,6 +27,8 @@
|
|||
"@logto/react": "1.0.0",
|
||||
"@logto/schemas": "workspace:*",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@microsoft/applicationinsights-react-js": "^3.4.1",
|
||||
"@microsoft/applicationinsights-web": "^2.8.11",
|
||||
"@parcel/compressor-brotli": "2.8.3",
|
||||
"@parcel/compressor-gzip": "2.8.3",
|
||||
"@parcel/core": "2.8.3",
|
||||
|
@ -92,6 +94,7 @@
|
|||
"stylelint": "^15.0.0",
|
||||
"superstruct": "^0.16.0",
|
||||
"swr": "^1.3.0",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.9.4",
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@ import OverlayScrollbar from '@/components/OverlayScrollbar';
|
|||
import TextInput from '@/components/TextInput';
|
||||
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
|
||||
import * as pageLayout from '@/onboarding/scss/layout.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import ActionBar from '../../components/ActionBar';
|
||||
import { CardSelector, MultiCardSelector } from '../../components/CardSelector';
|
||||
|
@ -20,7 +21,8 @@ import { getOnboardingPage } from '../../utils';
|
|||
import * as styles from './index.module.scss';
|
||||
import { titleOptions, companySizeOptions, reasonOptions } from './options';
|
||||
|
||||
const About = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function About() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
@ -138,6 +140,6 @@ const About = () => {
|
|||
</ActionBar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default About;
|
||||
export default withAppInsights(About);
|
||||
|
|
|
@ -11,10 +11,12 @@ import { TenantsContext } from '@/contexts/TenantsProvider';
|
|||
import Reservation from '@/onboarding/components/Reservation';
|
||||
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
|
||||
import * as pageLayout from '@/onboarding/scss/layout.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
const Congrats = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Congrats() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { update } = useUserOnboardingData();
|
||||
const { navigate, currentTenantId } = useContext(TenantsContext);
|
||||
|
@ -54,6 +56,6 @@ const Congrats = () => {
|
|||
</OverlayScrollbar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Congrats;
|
||||
export default withAppInsights(Congrats);
|
||||
|
|
|
@ -23,6 +23,7 @@ import * as pageLayout from '@/onboarding/scss/layout.module.scss';
|
|||
import type { OnboardingSieConfig } from '@/onboarding/types';
|
||||
import { Authentication, OnboardingPage } from '@/onboarding/types';
|
||||
import { getOnboardingPage } from '@/onboarding/utils';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
import { buildUrl } from '@/utils/url';
|
||||
import { uriValidator } from '@/utils/validator';
|
||||
|
||||
|
@ -34,7 +35,8 @@ import { authenticationOptions, identifierOptions } from './options';
|
|||
import { defaultOnboardingSieConfig } from './sie-config-templates';
|
||||
import { parser } from './utils';
|
||||
|
||||
const SignInExperience = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function SignInExperience() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
const { data: signInExperience, mutate } = useSWR<SignInExperienceType, RequestError>(
|
||||
|
@ -242,6 +244,6 @@ const SignInExperience = () => {
|
|||
</ActionBar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default SignInExperience;
|
||||
export default withAppInsights(SignInExperience);
|
||||
|
|
|
@ -12,6 +12,7 @@ import ActionBar from '@/onboarding/components/ActionBar';
|
|||
import { CardSelector } from '@/onboarding/components/CardSelector';
|
||||
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
|
||||
import * as pageLayout from '@/onboarding/scss/layout.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import type { Questionnaire } from '../../types';
|
||||
import { OnboardingPage } from '../../types';
|
||||
|
@ -19,7 +20,8 @@ import { getOnboardingPage } from '../../utils';
|
|||
import * as styles from './index.module.scss';
|
||||
import { deploymentTypeOptions, projectOptions } from './options';
|
||||
|
||||
const Welcome = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Welcome() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
@ -105,6 +107,6 @@ const Welcome = () => {
|
|||
</ActionBar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Welcome;
|
||||
export default withAppInsights(Welcome);
|
||||
|
|
|
@ -25,11 +25,13 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useApi from '@/hooks/use-api';
|
||||
import useTheme from '@/hooks/use-theme';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
import { ApiResourceDetailsOutletContext } from './types';
|
||||
|
||||
const ApiResourceDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function ApiResourceDetails() {
|
||||
const { pathname } = useLocation();
|
||||
const { id } = useParams();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
@ -154,6 +156,6 @@ const ApiResourceDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default ApiResourceDetails;
|
||||
export default withAppInsights(ApiResourceDetails);
|
||||
|
|
|
@ -23,6 +23,7 @@ import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
|||
import useTheme from '@/hooks/use-theme';
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
import { buildUrl } from '@/utils/url';
|
||||
|
||||
import CreateForm from './components/CreateForm';
|
||||
|
@ -34,7 +35,8 @@ const createApiResourcePathname = `${apiResourcesPathname}/create`;
|
|||
const buildDetailsPathname = (id: string) =>
|
||||
`${apiResourcesPathname}/${id}/${ApiResourceDetailsTabs.Settings}`;
|
||||
|
||||
const ApiResources = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function ApiResources() {
|
||||
const { pathname, search } = useLocation();
|
||||
const isCreateNew = pathname.endsWith('/create');
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
@ -146,6 +148,6 @@ const ApiResources = () => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default ApiResources;
|
||||
export default withAppInsights(ApiResources);
|
||||
|
|
|
@ -28,6 +28,7 @@ import useApi from '@/hooks/use-api';
|
|||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import { applicationTypeI18nKey } from '@/types/applications';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import Guide from '../Applications/components/Guide';
|
||||
import AdvancedSettings from './components/AdvancedSettings';
|
||||
|
@ -40,7 +41,8 @@ const mapToUriFormatArrays = (value?: string[]) =>
|
|||
const mapToUriOriginFormatArrays = (value?: string[]) =>
|
||||
value?.filter(Boolean).map((uri) => decodeURIComponent(new URL(uri).origin));
|
||||
|
||||
const ApplicationDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function ApplicationDetails() {
|
||||
const { id } = useParams();
|
||||
const { pathname } = useLocation();
|
||||
const isGuideView = !!id && pathname === `/applications/${id}/guide`;
|
||||
|
@ -236,6 +238,6 @@ const ApplicationDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default ApplicationDetails;
|
||||
export default withAppInsights(ApplicationDetails);
|
||||
|
|
|
@ -17,6 +17,7 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { applicationTypeI18nKey } from '@/types/applications';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
import { buildUrl } from '@/utils/url';
|
||||
|
||||
import ApplicationsPlaceholder from './components/ApplicationsPlaceholder';
|
||||
|
@ -29,7 +30,8 @@ const createApplicationPathname = `${applicationsPathname}/create`;
|
|||
const buildDetailsPathname = (id: string) => `${applicationsPathname}/${id}`;
|
||||
const buildGuidePathname = (id: string) => `${buildDetailsPathname(id)}/guide`;
|
||||
|
||||
const Applications = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Applications() {
|
||||
const navigate = useNavigate();
|
||||
const { pathname, search } = useLocation();
|
||||
const isShowingCreationForm = pathname === createApplicationPathname;
|
||||
|
@ -138,6 +140,6 @@ const Applications = () => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Applications;
|
||||
export default withAppInsights(Applications);
|
||||
|
|
|
@ -18,6 +18,7 @@ import UserName from '@/components/UserName';
|
|||
import { logEventTitle } from '@/consts/logs';
|
||||
import type { RequestError } from '@/hooks/use-api';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import EventIcon from './components/EventIcon';
|
||||
import * as styles from './index.module.scss';
|
||||
|
@ -28,7 +29,8 @@ const getAuditLogDetailsRelatedResourceLink = (pathname: string) =>
|
|||
const getDetailsTabNavLink = (logId: string, userId?: string) =>
|
||||
userId ? `/users/${userId}/logs/${logId}` : `/audit-logs/${logId}`;
|
||||
|
||||
const AuditLogDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function AuditLogDetails() {
|
||||
const { id, logId } = useParams();
|
||||
const { pathname } = useLocation();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
@ -127,6 +129,6 @@ const AuditLogDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default AuditLogDetails;
|
||||
export default withAppInsights(AuditLogDetails);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import AuditLogTable from '@/components/AuditLogTable';
|
||||
import CardTitle from '@/components/CardTitle';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
const AuditLogs = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function AuditLogs() {
|
||||
return (
|
||||
<div className={resourcesStyles.container}>
|
||||
<div className={resourcesStyles.headline}>
|
||||
|
@ -11,6 +13,6 @@ const AuditLogs = () => {
|
|||
<AuditLogTable className={resourcesStyles.table} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default AuditLogs;
|
||||
export default withAppInsights(AuditLogs);
|
||||
|
|
|
@ -28,6 +28,7 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useApi from '@/hooks/use-api';
|
||||
import useConnectorInUse from '@/hooks/use-connector-in-use';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import CreateForm from '../Connectors/components/CreateForm';
|
||||
import ConnectorContent from './components/ConnectorContent';
|
||||
|
@ -40,7 +41,8 @@ import * as styles from './index.module.scss';
|
|||
const getConnectorsPathname = (isSocial: boolean) =>
|
||||
`/connectors/${isSocial ? ConnectorsTabs.Social : ConnectorsTabs.Passwordless}`;
|
||||
|
||||
const ConnectorDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function ConnectorDetails() {
|
||||
const { pathname } = useLocation();
|
||||
const { connectorId } = useParams();
|
||||
const { mutate: mutateGlobal } = useSWRConfig();
|
||||
|
@ -233,6 +235,6 @@ const ConnectorDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default ConnectorDetails;
|
||||
export default withAppInsights(ConnectorDetails);
|
||||
|
|
|
@ -22,6 +22,7 @@ import useConnectorGroups from '@/hooks/use-connector-groups';
|
|||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||
import DemoConnectorNotice from '@/onboarding/components/DemoConnectorNotice';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import ConnectorDeleteButton from './components/ConnectorDeleteButton';
|
||||
import ConnectorName from './components/ConnectorName';
|
||||
|
@ -58,7 +59,8 @@ const isConnectorType = (value: string): value is ConnectorType =>
|
|||
const parseToConnectorType = (value?: string): ConnectorType | undefined =>
|
||||
conditional(value && isConnectorType(value) && value);
|
||||
|
||||
const Connectors = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Connectors() {
|
||||
const { tab = ConnectorsTabs.Passwordless, createType, factoryId } = useParams();
|
||||
const createConnectorType = parseToConnectorType(createType);
|
||||
const navigate = useNavigate();
|
||||
|
@ -222,6 +224,6 @@ const Connectors = () => {
|
|||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Connectors;
|
||||
export default withAppInsights(Connectors);
|
||||
|
|
|
@ -17,6 +17,7 @@ import AppError from '@/components/AppError';
|
|||
import Card from '@/components/Card';
|
||||
import TextInput from '@/components/TextInput';
|
||||
import type { RequestError } from '@/hooks/use-api';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import Block from './components/Block';
|
||||
import ChartTooltip from './components/ChartTooltip';
|
||||
|
@ -35,7 +36,8 @@ const tickFormatter = new Intl.NumberFormat('en-US', {
|
|||
notation: 'compact',
|
||||
});
|
||||
|
||||
const Dashboard = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Dashboard() {
|
||||
const [date, setDate] = useState<string>(format(Date.now(), 'yyyy-MM-dd'));
|
||||
const { data: totalData, error: totalError } = useSWR<TotalUsersResponse, RequestError>(
|
||||
'api/dashboard/users/total'
|
||||
|
@ -148,6 +150,6 @@ const Dashboard = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Dashboard;
|
||||
export default withAppInsights(Dashboard);
|
||||
|
|
|
@ -8,12 +8,14 @@ import Card from '@/components/Card';
|
|||
import ConfirmModal from '@/components/ConfirmModal';
|
||||
import Spacer from '@/components/Spacer';
|
||||
import useUserPreferences from '@/hooks/use-user-preferences';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import Skeleton from './components/Skeleton';
|
||||
import useGetStartedMetadata from './hook';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
const GetStarted = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function GetStarted() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
const { data, isLoading } = useGetStartedMetadata();
|
||||
|
@ -83,6 +85,6 @@ const GetStarted = () => {
|
|||
</ConfirmModal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default GetStarted;
|
||||
export default withAppInsights(GetStarted);
|
||||
|
|
|
@ -11,6 +11,7 @@ import { isCloud } from '@/consts/cloud';
|
|||
import { useStaticApi } from '@/hooks/use-api';
|
||||
import useCurrentUser from '@/hooks/use-current-user';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import BasicUserInfoSection from './components/BasicUserInfoSection';
|
||||
import CardContent from './components/CardContent';
|
||||
|
@ -20,7 +21,8 @@ import Skeleton from './components/Skeleton';
|
|||
import DeleteAccountModal from './containers/DeleteAccountModal';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
const Profile = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Profile() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
const api = useStaticApi({ prefixUrl: adminTenantEndpoint, resourceIndicator: meApi.indicator });
|
||||
|
@ -98,6 +100,6 @@ const Profile = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Profile;
|
||||
export default withAppInsights(Profile);
|
||||
|
|
|
@ -21,11 +21,13 @@ import { RoleDetailsTabs } from '@/consts/page-tabs';
|
|||
import type { RequestError } from '@/hooks/use-api';
|
||||
import useApi from '@/hooks/use-api';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
import { RoleDetailsOutletContext } from './types';
|
||||
|
||||
const RoleDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function RoleDetails() {
|
||||
const { pathname } = useLocation();
|
||||
const { id } = useParams();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
@ -147,6 +149,6 @@ const RoleDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default RoleDetails;
|
||||
export default withAppInsights(RoleDetails);
|
||||
|
|
|
@ -18,6 +18,7 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
||||
import * as pageStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
import { buildUrl, formatSearchKeyword } from '@/utils/url';
|
||||
|
||||
import AssignedUsers from './components/AssignedUsers';
|
||||
|
@ -30,7 +31,8 @@ const buildDetailsPathname = (id: string) => `${rolesPathname}/${id}`;
|
|||
|
||||
const pageSize = defaultPageSize;
|
||||
|
||||
const Roles = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Roles() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { pathname, search } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
@ -158,6 +160,6 @@ const Roles = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Roles;
|
||||
export default withAppInsights(Roles);
|
||||
|
|
|
@ -21,6 +21,7 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useApi from '@/hooks/use-api';
|
||||
import useConfigs from '@/hooks/use-configs';
|
||||
import useUiLanguages from '@/hooks/use-ui-languages';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import Preview from './components/Preview';
|
||||
import SignUpAndSignInChangePreview from './components/SignUpAndSignInChangePreview';
|
||||
|
@ -55,7 +56,8 @@ const PageWrapper = ({ children }: PageWrapperProps) => (
|
|||
</div>
|
||||
);
|
||||
|
||||
const SignInExperience = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function SignInExperience() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { tab } = useParams();
|
||||
const { data, error, mutate } = useSWR<SignInExperienceType, RequestError>('api/sign-in-exp');
|
||||
|
@ -231,6 +233,6 @@ const SignInExperience = () => {
|
|||
/>
|
||||
</PageWrapper>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default SignInExperience;
|
||||
export default withAppInsights(SignInExperience);
|
||||
|
|
|
@ -25,13 +25,15 @@ import type { RequestError } from '@/hooks/use-api';
|
|||
import useApi from '@/hooks/use-api';
|
||||
import * as detailsStyles from '@/scss/details.module.scss';
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
||||
import UserAccountInformation from '../../components/UserAccountInformation';
|
||||
import ResetPasswordForm from './components/ResetPasswordForm';
|
||||
import * as styles from './index.module.scss';
|
||||
import { UserDetailsOutletContext } from './types';
|
||||
|
||||
const UserDetails = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function UserDetails() {
|
||||
const { pathname } = useLocation();
|
||||
const isPageHasTable =
|
||||
pathname.endsWith(UserDetailsTabs.Roles) || pathname.endsWith(UserDetailsTabs.Logs);
|
||||
|
@ -195,6 +197,6 @@ const UserDetails = () => {
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default UserDetails;
|
||||
export default withAppInsights(UserDetails);
|
||||
|
|
|
@ -21,6 +21,7 @@ import { UserDetailsTabs } from '@/consts/page-tabs';
|
|||
import type { RequestError } from '@/hooks/use-api';
|
||||
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
import { buildUrl, formatSearchKeyword } from '@/utils/url';
|
||||
|
||||
import CreateForm from './components/CreateForm';
|
||||
|
@ -31,7 +32,8 @@ const usersPathname = '/users';
|
|||
const createUserPathname = `${usersPathname}/create`;
|
||||
const buildDetailsPathname = (id: string) => `${usersPathname}/${id}/${UserDetailsTabs.Settings}`;
|
||||
|
||||
const Users = () => {
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
function Users() {
|
||||
const { pathname, search } = useLocation();
|
||||
const isCreateNew = pathname === createUserPathname;
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
@ -172,6 +174,6 @@ const Users = () => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Users;
|
||||
export default withAppInsights(Users);
|
||||
|
|
40
packages/console/src/utils/app-insights.ts
Normal file
40
packages/console/src/utils/app-insights.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { ReactPlugin, withAITracking } from '@microsoft/applicationinsights-react-js';
|
||||
import { ApplicationInsights } from '@microsoft/applicationinsights-web';
|
||||
import type { Optional } from '@silverhand/essentials';
|
||||
import type { ComponentType } from 'react';
|
||||
|
||||
import { isCloud } from '@/consts/cloud';
|
||||
|
||||
/* eslint-disable @silverhand/fp/no-mutation, @silverhand/fp/no-let */
|
||||
let reactPlugin: Optional<ReactPlugin>;
|
||||
let appInsights: Optional<ApplicationInsights>;
|
||||
|
||||
const initAppInsights = () => {
|
||||
const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING;
|
||||
|
||||
if (!isCloud || !connectionString) {
|
||||
return;
|
||||
}
|
||||
// https://github.com/microsoft/applicationinsights-react-js#readme
|
||||
reactPlugin = new ReactPlugin();
|
||||
appInsights = new ApplicationInsights({
|
||||
config: {
|
||||
connectionString,
|
||||
enableAutoRouteTracking: true,
|
||||
extensions: [reactPlugin],
|
||||
},
|
||||
});
|
||||
|
||||
appInsights.loadAppInsights();
|
||||
};
|
||||
/* eslint-enable @silverhand/fp/no-mutation, @silverhand/fp/no-let */
|
||||
|
||||
initAppInsights();
|
||||
|
||||
export const withAppInsights = (Component: ComponentType) => {
|
||||
if (!isCloud || !reactPlugin) {
|
||||
return Component;
|
||||
}
|
||||
|
||||
return withAITracking(reactPlugin, Component);
|
||||
};
|
115
pnpm-lock.yaml
115
pnpm-lock.yaml
|
@ -190,6 +190,8 @@ importers:
|
|||
'@logto/react': 1.0.0
|
||||
'@logto/schemas': workspace:*
|
||||
'@mdx-js/react': ^1.6.22
|
||||
'@microsoft/applicationinsights-react-js': ^3.4.1
|
||||
'@microsoft/applicationinsights-web': ^2.8.11
|
||||
'@parcel/compressor-brotli': 2.8.3
|
||||
'@parcel/compressor-gzip': 2.8.3
|
||||
'@parcel/core': 2.8.3
|
||||
|
@ -255,6 +257,7 @@ importers:
|
|||
stylelint: ^15.0.0
|
||||
superstruct: ^0.16.0
|
||||
swr: ^1.3.0
|
||||
tslib: ^2.4.1
|
||||
typescript: ^4.9.4
|
||||
zod: ^3.20.2
|
||||
devDependencies:
|
||||
|
@ -267,6 +270,8 @@ importers:
|
|||
'@logto/react': 1.0.0_react@18.2.0
|
||||
'@logto/schemas': link:../schemas
|
||||
'@mdx-js/react': 1.6.22_react@18.2.0
|
||||
'@microsoft/applicationinsights-react-js': 3.4.1_ru3n4sc2jwbij7oomq3xpksl5a
|
||||
'@microsoft/applicationinsights-web': 2.8.11_tslib@2.4.1
|
||||
'@parcel/compressor-brotli': 2.8.3_@parcel+core@2.8.3
|
||||
'@parcel/compressor-gzip': 2.8.3_@parcel+core@2.8.3
|
||||
'@parcel/core': 2.8.3
|
||||
|
@ -332,6 +337,7 @@ importers:
|
|||
stylelint: 15.0.0
|
||||
superstruct: 0.16.0
|
||||
swr: 1.3.0_react@18.2.0
|
||||
tslib: 2.4.1
|
||||
typescript: 4.9.4
|
||||
zod: 3.20.2
|
||||
|
||||
|
@ -2578,10 +2584,119 @@ packages:
|
|||
resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==}
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-analytics-js/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-RwGnRDIAjyX/5yDJOueGfQkKwg7B1FTeIsv4wJ303CJD2wKSxxhE9rqYIPl5tKGqzv/uzmE/fiKuqiVlp7vcLg==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-channel-js/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-DGDNzT4DMlSvUzWjA4y3tDg47+QYOPV+W07vlfdPwGgLwrl4n6Q4crrW8Y/IOpthHAKDU8rolSAUvP3NqxPi4Q==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-common/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-Cxu4gRajkYv9buEtrcLGHK97AqGK62feN9jH9/JSjUSiSFhbnWtYvEg1EMqMI/P4pneu53yLJloITB+TKwmK7A==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-core-js/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-6ScXplyb9Zb0K6TQRfqStm20j5lIe/Dslf65ozows6ibDcKkWl2ZdqzFhymVJZz1WRNpSyD4aA8qnqmslIER6g==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-dependencies-js/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-eCjNouBvvnu+E3jLdfQgSIx3AUvmBDd14ZJNOjkvsaURhgRyWkBX3enT+RjrVrqyNQ74ZpHZpIJEqj90l28SsA==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-properties-js/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-cuX8jwycBYX81SXmGTNK7JSJod3l8l3FIH0HPgPayCQy7CdHYlfKPTKE9q3I9qD1GO/3ER9yozuKpE+12Wk/2w==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-react-js/3.4.1_ru3n4sc2jwbij7oomq3xpksl5a:
|
||||
resolution: {integrity: sha512-oosMkymmkkulUdFcUbqKc64Li0KpItmV/pClOr4DCLAxbitCjHDkKdxodvpUzMHVs1ko9cHP360oc1QVXprhXQ==}
|
||||
peerDependencies:
|
||||
history: '>= 4.10.1'
|
||||
react: '>= 17.0.1 || ^18.0.0'
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
history: 5.3.0
|
||||
react: 18.2.0
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-shims/2.0.2:
|
||||
resolution: {integrity: sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg==}
|
||||
dev: true
|
||||
|
||||
/@microsoft/applicationinsights-web-snippet/1.0.1:
|
||||
resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==}
|
||||
dev: false
|
||||
|
||||
/@microsoft/applicationinsights-web/2.8.11_tslib@2.4.1:
|
||||
resolution: {integrity: sha512-cLJl3MLQtvbwXU0hvFLl6S2/rIdoZKpZL8cvdaT0cXqd5XIiMbeUOxWHLf2hxT8IlIeVlu5nnFILeRYOFZowvw==}
|
||||
peerDependencies:
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
'@microsoft/applicationinsights-analytics-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-channel-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-common': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-core-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-dependencies-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-properties-js': 2.8.11_tslib@2.4.1
|
||||
'@microsoft/applicationinsights-shims': 2.0.2
|
||||
'@microsoft/dynamicproto-js': 1.1.8
|
||||
tslib: 2.4.1
|
||||
dev: true
|
||||
|
||||
/@microsoft/dynamicproto-js/1.1.8:
|
||||
resolution: {integrity: sha512-j4ZgOZRtX0LTUgKq+4tRQotgwH03HH/mLkYbcgFBBJ9XKTDc4NIGzZeam2UQMzwz+5IVN0SXexNbbsz5B0b/og==}
|
||||
dev: true
|
||||
|
||||
/@mischnic/json-sourcemap/0.1.0:
|
||||
resolution: {integrity: sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
|
Loading…
Reference in a new issue