feat: 조직도 소속원 폼 작업
This commit is contained in:
@@ -2,7 +2,9 @@ export { UserOrganizationApi } from "./api/user-organization-service";
|
||||
export {
|
||||
userOrganizationFormSchema,
|
||||
type TreeUserOrganization,
|
||||
type TreeUser,
|
||||
type UserOrganizationFormData,
|
||||
type UserOrganizationPayloadData,
|
||||
type User,
|
||||
type SearchUser,
|
||||
} from "./model/user-organization-interface";
|
||||
|
||||
@@ -53,21 +53,24 @@ export interface TreeUserOrganization {
|
||||
children: TreeUserOrganization[];
|
||||
}
|
||||
|
||||
export const userOrganizationPayloadSchema = z.object({
|
||||
mode: z.string(),
|
||||
ognzSn: z.number(),
|
||||
userUnqId: z.string(),
|
||||
jbpsSeCd: z.string(),
|
||||
jbgdSeCd: z.string(),
|
||||
sortSeq: z.number(),
|
||||
});
|
||||
|
||||
export const userOrganizationFormSchema = z.object({
|
||||
userOrganization: z.array(
|
||||
z.object({
|
||||
mode: z.string(),
|
||||
ognzSn: z.number(),
|
||||
userUnqId: z.string(),
|
||||
jbpsSeCd: z.string(),
|
||||
jbgdSeCd: z.string(),
|
||||
sortSeq: z.number(),
|
||||
}),
|
||||
),
|
||||
userOrganization: z.array(userOrganizationPayloadSchema),
|
||||
});
|
||||
|
||||
export type UserOrganizationList = PageableList<User>;
|
||||
export type SearchUserList = PageableList<SearchUser>;
|
||||
export type UserOrganizationPayloadData = z.infer<
|
||||
typeof userOrganizationPayloadSchema
|
||||
>;
|
||||
export type UserOrganizationFormData = z.infer<
|
||||
typeof userOrganizationFormSchema
|
||||
>;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { DropOptions, NodeModel } from "@minoru/react-dnd-treeview";
|
||||
import type { UserOrganization, User } from "@/entities/user-organization";
|
||||
import type {
|
||||
TreeUserOrganization,
|
||||
TreeUser,
|
||||
} from "@/entities/user-organization";
|
||||
import type { TreeMenu, TreeNode } from "../model/menu-interface";
|
||||
|
||||
export const generateMenuTreeData = (
|
||||
@@ -108,11 +111,11 @@ export const handleNodeTextChange =
|
||||
};
|
||||
|
||||
export const generateUserOrganizationTreeData = (
|
||||
organizations: UserOrganization[],
|
||||
): NodeModel<UserOrganization | User>[] => {
|
||||
return organizations.reduce<NodeModel<UserOrganization | User>[]>(
|
||||
organizations: TreeUserOrganization[],
|
||||
): NodeModel<TreeUserOrganization | TreeUser>[] => {
|
||||
return organizations.reduce<NodeModel<TreeUserOrganization | TreeUser>[]>(
|
||||
(acc, org) => {
|
||||
const orgNode: NodeModel<UserOrganization> = {
|
||||
const orgNode: NodeModel<TreeUserOrganization> = {
|
||||
id: org.ognzSn,
|
||||
parent: org.upOgnzSn ?? 0,
|
||||
text: org.ognzNm,
|
||||
@@ -145,9 +148,9 @@ export const generateUserOrganizationTreeData = (
|
||||
};
|
||||
|
||||
export const filterUserOrganizationTreeDataByKeyword = (
|
||||
treeData: NodeModel<UserOrganization | User>[],
|
||||
treeData: NodeModel<TreeUserOrganization | TreeUser>[],
|
||||
keyword: string,
|
||||
): NodeModel<UserOrganization | User>[] => {
|
||||
): NodeModel<TreeUserOrganization | TreeUser>[] => {
|
||||
return Array.from(
|
||||
treeData.reduce((matchedNodes, node) => {
|
||||
if (!node.text.includes(keyword)) return matchedNodes;
|
||||
@@ -163,6 +166,6 @@ export const filterUserOrganizationTreeDataByKeyword = (
|
||||
}
|
||||
|
||||
return matchedNodes;
|
||||
}, new Set<NodeModel<UserOrganization | User>>()),
|
||||
}, new Set<NodeModel<TreeUserOrganization | TreeUser>>()),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
import { cn } from "@common/components/lib";
|
||||
import {
|
||||
UserOrganizationApi,
|
||||
type User,
|
||||
type TreeUserOrganization,
|
||||
type TreeUser,
|
||||
} from "@/entities/user-organization";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import {
|
||||
@@ -30,10 +30,10 @@ import {
|
||||
generateUserOrganizationTreeData,
|
||||
} from "../lib/utils";
|
||||
|
||||
type TreeModel = TreeUserOrganization | User;
|
||||
type TreeModel = TreeUserOrganization | TreeUser;
|
||||
|
||||
interface OrganizationSearchDialogProps {
|
||||
handleUserSelect: (user: User) => void;
|
||||
handleUserSelect: (user: TreeUser) => void;
|
||||
}
|
||||
|
||||
function OrganizationSearchDialog({
|
||||
@@ -53,7 +53,7 @@ function OrganizationSearchDialog({
|
||||
|
||||
const handleSelectNode = (node: NodeModel<TreeModel>) => {
|
||||
setSelectedNode(node);
|
||||
handleUserSelect(node.data as User);
|
||||
handleUserSelect(node.data as TreeUser);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
} from "@common/components";
|
||||
import type { BoardPopup } from "@/entities/board";
|
||||
import type { Contents } from "@/entities/content";
|
||||
import type { User } from "@/entities/user-organization";
|
||||
import type { TreeUser } from "@/entities/user-organization";
|
||||
import { FormItem, FormControl, FormField } from "@/shared/ui/form";
|
||||
import type { MenuFormData, MenuType } from "../model/menu-interface";
|
||||
import { OrganizationSearchDialog } from "./organization-search-dialog";
|
||||
@@ -37,7 +37,7 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) {
|
||||
form.setValue("menuLnkgSnNm", content.contsTtl);
|
||||
};
|
||||
|
||||
const handleUserSelect = (user: User) => {
|
||||
const handleUserSelect = (user: TreeUser) => {
|
||||
form.setValue("menuPicUserUnqId", user.userUnqId);
|
||||
form.setValue("menuPicUserUnqIdNm", user.userNm);
|
||||
};
|
||||
|
||||
@@ -227,7 +227,9 @@ function OrganizationPage() {
|
||||
handleUpdate={updateOrganization}
|
||||
handleDelete={deleteOrganization}
|
||||
/>
|
||||
<UserOrganizationSection ognzSn={selectedOrganization?.ognzSn} />
|
||||
{selectedOrganization?.ognzSn && (
|
||||
<UserOrganizationSection ognzSn={selectedOrganization.ognzSn} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ type UserOrganizationSectionProps = {
|
||||
function UserOrganizationSection({ ognzSn }: UserOrganizationSectionProps) {
|
||||
const [userList, setUserList] = useState<User[]>([]);
|
||||
|
||||
const { data } = useQuery({
|
||||
const { data: userOrganizationList } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.USER_ORGANIZATION, ognzSn],
|
||||
queryFn: () =>
|
||||
UserOrganizationApi.getUserOrganizationList({ ognzSn: ognzSn! }),
|
||||
@@ -53,7 +53,7 @@ function UserOrganizationSection({ ognzSn }: UserOrganizationSectionProps) {
|
||||
resolver: zodResolver(userOrganizationFormSchema),
|
||||
values: {
|
||||
userOrganization: [
|
||||
...(data?.content ?? []).map((user) => ({
|
||||
...userList.map((user) => ({
|
||||
mode: user.mode,
|
||||
ognzSn: user.ognzSn,
|
||||
userUnqId: user.userUnqId,
|
||||
@@ -64,14 +64,13 @@ function UserOrganizationSection({ ognzSn }: UserOrganizationSectionProps) {
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { append } = useFieldArray({
|
||||
control: form.control,
|
||||
name: "userOrganization",
|
||||
});
|
||||
|
||||
const table = useReactTable({
|
||||
data: data?.content ?? [],
|
||||
data: userList,
|
||||
columns: createColumns(
|
||||
form,
|
||||
(props) => <CodeSelect codeData={jobPositionCodes} {...props} />,
|
||||
@@ -109,8 +108,9 @@ function UserOrganizationSection({ ognzSn }: UserOrganizationSectionProps) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.content) setUserList(data.content);
|
||||
}, [data]);
|
||||
if (userOrganizationList?.content)
|
||||
setUserList(userOrganizationList.content);
|
||||
}, [userOrganizationList]);
|
||||
|
||||
return (
|
||||
<div className={cn("card card-border", !ognzSn && "hidden")}>
|
||||
@@ -134,6 +134,7 @@ function UserOrganizationSection({ ognzSn }: UserOrganizationSectionProps) {
|
||||
type CodeSelectProps = React.ComponentPropsWithoutRef<typeof Select> & {
|
||||
codeData?: ICode[];
|
||||
};
|
||||
|
||||
const CodeSelect = ({ codeData, ...props }: CodeSelectProps) => {
|
||||
if (!codeData) return null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user