From 0b568f277ea7bebdbe13997e4b0af84a3dfaeb0b Mon Sep 17 00:00:00 2001 From: linxiaoxin Date: Sat, 27 Jul 2024 21:50:01 +0800 Subject: [PATCH] Added add new skill, edit, reload and save in front end --- app/(main)/questions/topics/page.tsx | 165 +++++++++++++++++++++++---- types/questions.d.ts | 3 +- 2 files changed, 142 insertions(+), 26 deletions(-) diff --git a/app/(main)/questions/topics/page.tsx b/app/(main)/questions/topics/page.tsx index 7f9d591..1c6c5b5 100644 --- a/app/(main)/questions/topics/page.tsx +++ b/app/(main)/questions/topics/page.tsx @@ -6,53 +6,168 @@ import { TreeTable } from 'primereact/treetable'; import { Column } from 'primereact/column'; import { InputText } from 'primereact/inputtext'; import { Button } from 'primereact/button'; -import { SelectButton } from 'primereact/selectbutton'; +import { ToggleButton } from 'primereact/togglebutton'; +import { warnOptionHasBeenMovedOutOfExperimental } from 'next/dist/server/config'; const ManageTopics = () => { + const [topicNodes, setTopicNodes] = useState([]); + const [topics, setTopics] = useState([]); + const [edited, setEdited] = useState(false); + const [expandedKeys, setExpandedKeys] = useState(); - const [topics, setTopics] = useState([]); - useEffect(()=>{ + const reload = () => { QuestionsService.getTopics().then((t) => { - var nodes = t.map( item => { - let childnode: any[] = []; - if(item.skills){ - childnode = item.skills.map( skill => { - return { "key": item.id+"-"+skill.id, - "data": { "name": skill.name , "active": skill.active, "type": "skill"} - }; - }); - } - return { "key" : item.id, "data" : { "name": item.name, "active": item.active, "type": "topic"}, children : childnode } - }); - setTopics(nodes); + setTopics(t); }); + } + + useEffect(()=>{ + reload(); + },[]); + + useEffect(()=>{ + var nodes = topics.map( item => { + let childnode: any[] = []; + if(item.skills){ + childnode = item.skills.map( skill => { + return { "key": item.id+"-"+skill.id, + "data": { "id": skill.id,"name": skill.name , "active": skill.active, "type": "skill", "edited": skill.edited} + }; + }); + } + return { "key" : item.id, "data" : { "id":item.id, "name": item.name, "active": item.active, "type": "topic", "edited": item.edited}, children : childnode } + }); + setTopicNodes(nodes); + + }, [topics]) - }, []) const actionTemplate = (node: any) => { return ( node.data.type === "skill" ||
- +
); }; + const activeTemplate = (node: any) => { + return( + onActiveStatusChange(node, e.target.value)}/> + ); + } + //edit active status + const onActiveStatusChange = (node: any, value: boolean) => { + var found = false; + let updatedTopics = topics.map( (t)=> { + if(node.data.type === 'topic' && t.id === node.key){ + t.active = value; + t.edited = true; + found = true; + } + else if(node.data.type === 'skill' && t.skills){ + t.skills.map((s) => { + if(s.id === node.data.id){ + s.active = value; + s.edited = true; + found = true; + } + }) + } + return t; + }); + if(found){ + setEdited(true); + setTopics(updatedTopics); + } + } //edit name - const onEditorValueChange = (options: any, value: string) => { + const onNameChange = (options: any, value: string) => { + var found = false; + let updatedTopics = topics.map( (t)=> { + if(options.node.data.type === 'topic' && t.id === options.node.key){ + t.name = value; + t.edited = true; + found = true; + } + else if(options.node.data.type === 'skill' && t.skills){ + t.skills.map((s) => { + if(s.id === options.node.data.id){ + s.name = value; + s.edited = true; + found = true; + } + }) + } + return t; + }); + if(found){ + setEdited(true); + setTopics(updatedTopics); + } + } + const nameEditor = (options: any) => { + return onNameChange(options, e.target.value) } onKeyDown={(e) => e.stopPropagation()} />; + }; + //add skill + const addSkill = (node: any)=> { + var found = false; + console.log("Add skills for ", node.key) + let updatedTopics = topics.map( (t)=> { + if(t.id === node.key){ + found = true; + let newSkill: Questions.Skill = { + name: "", + active: true, + edited: true, + topicId: node.key + } + //add skill + if(t.skills){ + t.skills.unshift(newSkill) + } + else{ + t.skills = [newSkill] + } + } + return t; + }); + if(found){ + setEdited(true); + setTopics(updatedTopics); + let _expandkey: any = {}; + _expandkey[node.key] = true; + setExpandedKeys(_expandkey) + } + } + //footer + const footer = ( +
+
+
+ {!edited ||
+
} +
+ ); + + //conditional formating + const rowClassName = (node: any) => { + return { 'p-highlight': node.data.edited }; } - const inputTextEditor = (options: any) => { - return onEditorValueChange(options, e.target.value)} onKeyDown={(e) => e.stopPropagation()} />; - }; return (
Manage Topics
- - - - + setExpandedKeys(e.value)} > + + +
diff --git a/types/questions.d.ts b/types/questions.d.ts index 4a8c87d..1feb79b 100644 --- a/types/questions.d.ts +++ b/types/questions.d.ts @@ -28,14 +28,15 @@ declare namespace Questions { name: string; active: boolean; skills: Skill[]; + edited: boolean = false; //false by default (only used by UI) } interface Skill{ id?: number; name: string; active: boolean; - topic_id: number; topicId: number; + edited: boolean = false; //false by default (only used by UI) } interface RetrieveQuestionRequest {