Change hooks for User, Org, Project, Job
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
import invariant from "tiny-invariant";
|
||||
import type { loader } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam/route";
|
||||
import { useOptionalProject } from "./useProject";
|
||||
import { useChanged } from "./useChanged";
|
||||
|
||||
export type MatchedJob = UseDataFunctionReturn<typeof loader>["job"];
|
||||
|
||||
@@ -31,3 +32,9 @@ export function useJob() {
|
||||
invariant(job, "Job must be defined");
|
||||
return job;
|
||||
}
|
||||
|
||||
export const useJobChanged = (
|
||||
action: (org: MatchedJob | undefined) => void
|
||||
) => {
|
||||
useChanged(useOptionalJob, action);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import {
|
||||
UseDataFunctionReturn,
|
||||
useTypedRouteLoaderData,
|
||||
@@ -7,6 +6,7 @@ import invariant from "tiny-invariant";
|
||||
import type { loader as orgLoader } from "~/routes/_app.orgs.$organizationSlug/route";
|
||||
import type { loader as appLoader } from "~/routes/_app/route";
|
||||
import { hydrateObject, useMatchesData } from "~/utils";
|
||||
import { useChanged } from "./useChanged";
|
||||
|
||||
export type MatchedOrganization = UseDataFunctionReturn<
|
||||
typeof appLoader
|
||||
@@ -61,43 +61,8 @@ function useOrganizationsFromMatchesData(paths: string[]) {
|
||||
>(routeMatch.data.organizations);
|
||||
}
|
||||
|
||||
export function useOrganizationChanged(
|
||||
export const useOrganizationChanged = (
|
||||
action: (org: MatchedOrganization | undefined) => void
|
||||
) {
|
||||
const previousOrganizationId = useRef<string | undefined>();
|
||||
const organization = useOptionalOrganization();
|
||||
|
||||
useEffect(() => {
|
||||
if (previousOrganizationId.current !== organization?.id) {
|
||||
action(organization);
|
||||
}
|
||||
|
||||
previousOrganizationId.current = organization?.id;
|
||||
}, [organization]);
|
||||
|
||||
useEffect(() => {
|
||||
if (organization !== undefined) return;
|
||||
action(organization);
|
||||
}, []);
|
||||
}
|
||||
|
||||
function useChanged<T extends { id: string }>(
|
||||
getItem: () => T | undefined,
|
||||
action: (item: T | undefined) => void
|
||||
) {
|
||||
const previousItemId = useRef<string | undefined>();
|
||||
const item = getItem();
|
||||
|
||||
useEffect(() => {
|
||||
if (previousItemId.current !== item?.id) {
|
||||
action(item);
|
||||
}
|
||||
|
||||
previousItemId.current = item?.id;
|
||||
}, [item]);
|
||||
|
||||
useEffect(() => {
|
||||
if (item !== undefined) return;
|
||||
action(item);
|
||||
}, []);
|
||||
}
|
||||
) => {
|
||||
useChanged(useOptionalOrganization, action);
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from "remix-typedjson";
|
||||
import invariant from "tiny-invariant";
|
||||
import type { loader } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam/route";
|
||||
import { useChanged } from "./useChanged";
|
||||
|
||||
export type MatchedProject = UseDataFunctionReturn<typeof loader>["project"];
|
||||
|
||||
@@ -22,3 +23,9 @@ export function useProject() {
|
||||
invariant(project, "Project must be defined");
|
||||
return project;
|
||||
}
|
||||
|
||||
export const useProjectChanged = (
|
||||
action: (org: MatchedProject | undefined) => void
|
||||
) => {
|
||||
useChanged(useOptionalProject, action);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { User } from "~/models/user.server";
|
||||
import { useMatchesData } from "~/utils";
|
||||
import { useChanged } from "./useChanged";
|
||||
|
||||
function isUser(user: any): user is User {
|
||||
return user && typeof user === "object" && typeof user.email === "string";
|
||||
@@ -22,3 +23,7 @@ export function useUser(): User {
|
||||
}
|
||||
return maybeUser;
|
||||
}
|
||||
|
||||
export function useUserChanged(callback: (user: User | undefined) => void) {
|
||||
useChanged(useOptionalUser, callback);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user