refactor(login/identites): identities improvements
- only one GraphQL call to Identities - LoginView is no more responsible for identities : App.vue is now reactively monitoring identities changes to initializeCurrentActor - Remove useLazyCurrentUserIdentities we now use useCurrentUserIdentities everywhere - Change identities to be possibly undefined instead of null to remove a useless trigger to watch in App.vue Related to #1806
This commit is contained in:
75
src/App.vue
75
src/App.vue
@@ -76,7 +76,7 @@ import { CONFIG } from "@/graphql/config";
|
|||||||
import { IConfig } from "@/types/config.model";
|
import { IConfig } from "@/types/config.model";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import RouteName from "@/router/name";
|
import RouteName from "@/router/name";
|
||||||
import { useLazyCurrentUserIdentities } from "./composition/apollo/actor";
|
import { useCurrentUserIdentities } from "./composition/apollo/actor";
|
||||||
|
|
||||||
const { result: configResult } = useQuery<{ config: IConfig }>(
|
const { result: configResult } = useQuery<{ config: IConfig }>(
|
||||||
CONFIG,
|
CONFIG,
|
||||||
@@ -145,23 +145,29 @@ interval.value = window.setInterval(async () => {
|
|||||||
}
|
}
|
||||||
}, 60000) as unknown as number;
|
}, 60000) as unknown as number;
|
||||||
|
|
||||||
const { load: loadIdentities } = useLazyCurrentUserIdentities();
|
const { identities } = useCurrentUserIdentities();
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
console.debug("Before mount App");
|
console.debug("App: onBeforeMount...");
|
||||||
if (initializeCurrentUser()) {
|
|
||||||
try {
|
// Try to init the user
|
||||||
const result = await loadIdentities();
|
if (!initializeCurrentUser()) return;
|
||||||
if (!result) return;
|
});
|
||||||
await initializeCurrentActor(result.loggedUser.actors);
|
|
||||||
} catch (err) {
|
watch(identities, async () => {
|
||||||
if (err instanceof NoIdentitiesException) {
|
// Try to init the identities and set one of them
|
||||||
await router.push({
|
console.log("identities has changed", identities.value);
|
||||||
name: RouteName.CREATE_IDENTITY,
|
try {
|
||||||
});
|
if (!identities.value) return;
|
||||||
} else {
|
|
||||||
throw err;
|
console.log("We will initializeCurrentActor");
|
||||||
}
|
await initializeCurrentActor(identities.value);
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof NoIdentitiesException) {
|
||||||
|
console.log("Route to CREATE_IDENTITY because user has no identity");
|
||||||
|
router.push({ name: RouteName.CREATE_IDENTITY });
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -258,43 +264,6 @@ const refreshApp = async (
|
|||||||
const showOfflineNetworkWarning = (): void => {
|
const showOfflineNetworkWarning = (): void => {
|
||||||
notifier?.error(t("You are offline"));
|
notifier?.error(t("You are offline"));
|
||||||
};
|
};
|
||||||
// const extractPageTitleFromRoute = (routeWatched: RouteLocation): string => {
|
|
||||||
// if (routeWatched.meta?.announcer?.message) {
|
|
||||||
// return routeWatched.meta?.announcer?.message();
|
|
||||||
// }
|
|
||||||
// return document.title;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// watch(route, (routeWatched) => {
|
|
||||||
// const pageTitle = extractPageTitleFromRoute(routeWatched);
|
|
||||||
// if (pageTitle) {
|
|
||||||
// // this.$announcer.polite(
|
|
||||||
// // t("Navigated to {pageTitle}", {
|
|
||||||
// // pageTitle,
|
|
||||||
// // }) as string
|
|
||||||
// // );
|
|
||||||
// }
|
|
||||||
// // Set the focus to the router view
|
|
||||||
// // https://marcus.io/blog/accessible-routing-vuejs
|
|
||||||
// setTimeout(() => {
|
|
||||||
// const focusTarget = (
|
|
||||||
// routerView.value?.$refs?.componentFocusTarget !== undefined
|
|
||||||
// ? routerView.value?.$refs?.componentFocusTarget
|
|
||||||
// : routerView.value?.$el
|
|
||||||
// ) as HTMLElement;
|
|
||||||
// if (focusTarget && focusTarget instanceof Element) {
|
|
||||||
// // Make focustarget programmatically focussable
|
|
||||||
// focusTarget.setAttribute("tabindex", "-1");
|
|
||||||
|
|
||||||
// // Focus element
|
|
||||||
// focusTarget.focus();
|
|
||||||
|
|
||||||
// // Remove tabindex from focustarget.
|
|
||||||
// // Reason: https://axesslab.com/skip-links/#update-3-a-comment-from-gov-uk
|
|
||||||
// focusTarget.removeAttribute("tabindex");
|
|
||||||
// }
|
|
||||||
// }, 0);
|
|
||||||
// });
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
} from "@/graphql/actor";
|
} from "@/graphql/actor";
|
||||||
import { IPerson } from "@/types/actor";
|
import { IPerson } from "@/types/actor";
|
||||||
import { ICurrentUser } from "@/types/current-user.model";
|
import { ICurrentUser } from "@/types/current-user.model";
|
||||||
import { useLazyQuery, useQuery } from "@vue/apollo-composable";
|
import { useQuery } from "@vue/apollo-composable";
|
||||||
import { computed, Ref, unref } from "vue";
|
import { computed, Ref, unref } from "vue";
|
||||||
import { useCurrentUserClient } from "./user";
|
import { useCurrentUserClient } from "./user";
|
||||||
|
|
||||||
@@ -22,26 +22,6 @@ export function useCurrentActorClient() {
|
|||||||
return { currentActor, error, loading };
|
return { currentActor, error, loading };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLazyCurrentUserIdentities() {
|
|
||||||
const { currentUser } = useCurrentUserClient();
|
|
||||||
return useLazyQuery<{
|
|
||||||
loggedUser: Pick<ICurrentUser, "actors">;
|
|
||||||
}>(
|
|
||||||
IDENTITIES,
|
|
||||||
{
|
|
||||||
// To ensure the request is re-executed when the user changes,
|
|
||||||
// we include a dummy `_user` parameter that's ignored by the server.
|
|
||||||
// This function does not depend on the user, the server identifies them by the token.
|
|
||||||
// So without this dummy parameter, the GraphQL call is not automatically reloaded
|
|
||||||
// when the actor changes.
|
|
||||||
_user: currentUser?.value?.id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fetchPolicy: "network-only",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useCurrentUserIdentities() {
|
export function useCurrentUserIdentities() {
|
||||||
const { currentUser } = useCurrentUserClient();
|
const { currentUser } = useCurrentUserClient();
|
||||||
|
|
||||||
@@ -71,7 +51,7 @@ export function useCurrentUserIdentities() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const identities = computed(() =>
|
const identities = computed(() =>
|
||||||
enabled.value ? result.value?.loggedUser?.actors : null
|
enabled.value ? result.value?.loggedUser?.actors : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
return { identities, error, loading };
|
return { identities, error, loading };
|
||||||
|
|||||||
@@ -133,10 +133,7 @@ import { IConfig } from "@/types/config.model";
|
|||||||
import { IUser } from "@/types/current-user.model";
|
import { IUser } from "@/types/current-user.model";
|
||||||
import { saveUserData, SELECTED_PROVIDERS } from "@/utils/auth";
|
import { saveUserData, SELECTED_PROVIDERS } from "@/utils/auth";
|
||||||
import { storeUserLocationAndRadiusFromUserSettings } from "@/utils/location";
|
import { storeUserLocationAndRadiusFromUserSettings } from "@/utils/location";
|
||||||
import {
|
import { NoIdentitiesException } from "@/utils/identity";
|
||||||
initializeCurrentActor,
|
|
||||||
NoIdentitiesException,
|
|
||||||
} from "@/utils/identity";
|
|
||||||
import { useMutation, useLazyQuery, useQuery } from "@vue/apollo-composable";
|
import { useMutation, useLazyQuery, useQuery } from "@vue/apollo-composable";
|
||||||
import { computed, reactive, ref, onMounted } from "vue";
|
import { computed, reactive, ref, onMounted } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
@@ -147,7 +144,6 @@ import { LoginError, LoginErrorCode } from "@/types/enums";
|
|||||||
import { useCurrentUserClient } from "@/composition/apollo/user";
|
import { useCurrentUserClient } from "@/composition/apollo/user";
|
||||||
import { useHead } from "@/utils/head";
|
import { useHead } from "@/utils/head";
|
||||||
import { enumTransformer, useRouteQuery } from "vue-use-route-query";
|
import { enumTransformer, useRouteQuery } from "vue-use-route-query";
|
||||||
import { useLazyCurrentUserIdentities } from "@/composition/apollo/actor";
|
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -185,8 +181,6 @@ const errorCode = useRouteQuery("code", null, enumTransformer(LoginErrorCode));
|
|||||||
|
|
||||||
// Login
|
// Login
|
||||||
const loginMutation = useMutation(LOGIN);
|
const loginMutation = useMutation(LOGIN);
|
||||||
// Load user identities
|
|
||||||
const currentUserIdentitiesQuery = useLazyCurrentUserIdentities();
|
|
||||||
// Update user in cache
|
// Update user in cache
|
||||||
const currentUserMutation = useMutation(UPDATE_CURRENT_USER_CLIENT);
|
const currentUserMutation = useMutation(UPDATE_CURRENT_USER_CLIENT);
|
||||||
// Retrieve preferred location
|
// Retrieve preferred location
|
||||||
@@ -225,18 +219,9 @@ const loginAction = async (e: Event) => {
|
|||||||
role: loginData.login.user.role,
|
role: loginData.login.user.role,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Step 3a: Retrieving user location
|
// Step 3: Retrieving user location
|
||||||
const loggedUserLocationPromise = loggedUserLocationQuery.load();
|
const loggedUserLocationPromise = loggedUserLocationQuery.load();
|
||||||
|
|
||||||
// Step 3b: Setuping user's identities
|
|
||||||
const currentUserIdentitiesResult = await currentUserIdentitiesQuery.load();
|
|
||||||
if (!currentUserIdentitiesResult) {
|
|
||||||
throw new Error("Loading user's identities failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
await initializeCurrentActor(currentUserIdentitiesResult.loggedUser.actors);
|
|
||||||
|
|
||||||
// Step 3a following
|
|
||||||
const loggedUserLocationResult = await loggedUserLocationPromise;
|
const loggedUserLocationResult = await loggedUserLocationPromise;
|
||||||
storeUserLocationAndRadiusFromUserSettings(
|
storeUserLocationAndRadiusFromUserSettings(
|
||||||
loggedUserLocationResult?.loggedUser?.settings?.location
|
loggedUserLocationResult?.loggedUser?.settings?.location
|
||||||
|
|||||||
Reference in New Issue
Block a user