Refactoring and reworking dbsetup route
This commit is contained in:
@@ -2,6 +2,7 @@ import { GetPostsAttributes } from "@/app/lib/actions/entityManagement/postActio
|
||||
import { Post, Project, Bucket, PostBucket, Attachment } from "@/models";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { UUID } from "crypto";
|
||||
import { EntityEditorTextArea } from '../input/EntityEditorTextArea';
|
||||
import {
|
||||
ChangeEventHandler,
|
||||
MouseEventHandler,
|
||||
@@ -49,23 +50,6 @@ export default function PostEditor({
|
||||
let [postProjectIDState, setPostProjectIDState] = useState(
|
||||
editorPost.project.id
|
||||
);
|
||||
let textbox: any = useRef(undefined);
|
||||
|
||||
// Autosize the text area
|
||||
function textAreaAutoSize(
|
||||
textbox: MutableRefObject<HTMLTextAreaElement>
|
||||
): void {
|
||||
if (!textbox.current || !textbox.current.style) return;
|
||||
textbox.current.style.height = "fit-content";
|
||||
textbox.current.style.height = `${textbox.current.scrollHeight}px`;
|
||||
}
|
||||
useLayoutEffect(() => textAreaAutoSize(textbox));
|
||||
|
||||
// Handle user input on the text area by updating state and autosizing the textfield
|
||||
const onTextAreaChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {
|
||||
setPostContentState(e.target.value); // Update State
|
||||
textAreaAutoSize(textbox); // Autosize the text area
|
||||
};
|
||||
|
||||
// Handle changing the selected project using the dropdown select
|
||||
const projectSelectionChange: ChangeEventHandler<HTMLSelectElement> = (e) =>
|
||||
@@ -102,14 +86,14 @@ export default function PostEditor({
|
||||
<h2 key="label-content" className="m-2">
|
||||
Content
|
||||
</h2>
|
||||
<textarea
|
||||
key="input-content"
|
||||
onChange={onTextAreaChange}
|
||||
ref={textbox}
|
||||
value={postContentState}
|
||||
style={{ height: "100%" }}
|
||||
className="w-[100%] min-h-auto h-content align-top text-start text-base line-clamp-6 m-2"
|
||||
/>
|
||||
<EntityEditorTextArea
|
||||
contentHook={{
|
||||
state: postContentState,
|
||||
setState: setPostContentState
|
||||
}}
|
||||
className={ "w-[100%] min-h-auto h-content align-top text-start text-base line-clamp-6 m-2" }
|
||||
>
|
||||
</EntityEditorTextArea>
|
||||
<h2 key="label-project" className="m-2">
|
||||
Project
|
||||
</h2>
|
||||
|
||||
@@ -1,38 +1,28 @@
|
||||
"use client";
|
||||
import React, { ReactNode } from "react";
|
||||
import React from "react";
|
||||
import EntityManagementTable from "../EntityManagementTable";
|
||||
import toast from "react-hot-toast";
|
||||
import { EditorRenderer, EditorState, PostTableCallbacks } from "./PostEditor";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { useState } from "react";
|
||||
import { Project, Post, Bucket } from "@/models";
|
||||
import { ActionResult } from "@/app/lib/actions/ActionResult";
|
||||
import { Attributes, InferAttributes } from "@sequelize/core";
|
||||
import { Project, Post, Bucket, User, PostAttributesWithBuckets } from "@/models";
|
||||
import { handleActionResult } from "@/app/lib/actions/clientActionHandler";
|
||||
|
||||
import {
|
||||
getPostsWithBucketsAndProject,
|
||||
GetPostsAttributes,
|
||||
PostServerActions,
|
||||
} from "@/app/lib/actions/entityManagement/postActions";
|
||||
import { PostViewProps } from "@/views/admin/ClientPostView";
|
||||
import { aifa } from "@/util/Utils";
|
||||
import { StateHook } from "../../../util/types/StateHook";
|
||||
|
||||
export type PostTableServerActions = {
|
||||
deletePost: (id: number) => Promise<ActionResult<boolean>>;
|
||||
getPosts: () => Promise<ActionResult<GetPostsAttributes[]>>;
|
||||
getProjects: () => Promise<ActionResult<Attributes<Project>[]>>;
|
||||
savePost: (
|
||||
data: Partial<Attributes<Post>>
|
||||
) => Promise<ActionResult<Attributes<Post>[]>>;
|
||||
// uploadAttachment: ()=> Promise<ActionResult<any>>
|
||||
};
|
||||
export type PostTableStateProps = {
|
||||
posts:StateHook<GetPostsAttributes[]>,
|
||||
editor:StateHook<EditorState>
|
||||
}
|
||||
|
||||
type PostTableProps = {
|
||||
children?: ReactNode;
|
||||
headings: Array<string>;
|
||||
posts: GetPostsAttributes[];
|
||||
projects: Attributes<Project>[];
|
||||
actions: PostTableServerActions;
|
||||
};
|
||||
export type PostTableProps = PostViewProps & {state:PostTableStateProps};
|
||||
|
||||
const aifa = (a: ReactNode, b: ReactNode) => (a ? a : b);
|
||||
|
||||
export default function PostTable({
|
||||
children,
|
||||
@@ -40,26 +30,20 @@ export default function PostTable({
|
||||
posts,
|
||||
projects,
|
||||
actions,
|
||||
state,
|
||||
}: PostTableProps) {
|
||||
// Init editor state. Make sure it is not opened by default
|
||||
const initEditorState: EditorState = {
|
||||
isEditorOpen: false,
|
||||
editorPost: posts[0],
|
||||
};
|
||||
// Set up required state hooks
|
||||
const [postsState, setPostsState] = useState(posts);
|
||||
const [editorState, setEditorState] = useState(initEditorState);
|
||||
|
||||
|
||||
// Define editor controls
|
||||
const editorControls = {
|
||||
closeEditor: () => {
|
||||
setEditorState({
|
||||
state.editor.setState({
|
||||
isEditorOpen: false,
|
||||
editorPost: posts[0],
|
||||
});
|
||||
},
|
||||
showEditor: (entry: GetPostsAttributes) => {
|
||||
setEditorState({
|
||||
state.editor.setState({
|
||||
isEditorOpen: true,
|
||||
editorPost: entry,
|
||||
});
|
||||
@@ -72,8 +56,8 @@ export default function PostTable({
|
||||
actions.deletePost(entry.id).then((actionResult) => {
|
||||
const result = handleActionResult(actionResult);
|
||||
if (!result) return;
|
||||
postsState.splice(postsState.indexOf(entry), 1);
|
||||
setPostsState([...postsState]);
|
||||
state.posts.state.splice(state.posts.state.indexOf(entry), 1);
|
||||
state.posts.setState([...state.posts.state]);
|
||||
toast.success("Removed Post:" + entry.id);
|
||||
});
|
||||
},
|
||||
@@ -86,7 +70,7 @@ export default function PostTable({
|
||||
getPostsServerActionResult
|
||||
);
|
||||
// Set Posts state
|
||||
if (result) setPostsState(result);
|
||||
if (result) state.posts.setState(result);
|
||||
});
|
||||
},
|
||||
savePost: (e: Partial<Attributes<Post>>) => {
|
||||
@@ -101,26 +85,19 @@ export default function PostTable({
|
||||
.then(getPostsWithBucketsAndProject)
|
||||
.then((res) => {
|
||||
const result = handleActionResult(res);
|
||||
if (result) setPostsState(result);
|
||||
if (result) state.posts.setState(result);
|
||||
})
|
||||
.then(editorControls.closeEditor)
|
||||
.then(postActions.refetch);
|
||||
},
|
||||
};
|
||||
|
||||
const callbacks: PostTableCallbacks = {
|
||||
savePost: postActions.savePost,
|
||||
closeEditor: editorControls.closeEditor,
|
||||
refetch: postActions.refetch,
|
||||
uploadAttachment: () => {},
|
||||
};
|
||||
|
||||
return (
|
||||
<EntityManagementTable
|
||||
entityName="Post"
|
||||
headings={headings}
|
||||
>
|
||||
{postsState.map((post: GetPostsAttributes) => (
|
||||
{state.posts.state.map((post: GetPostsAttributes) => (
|
||||
<React.Fragment key={`postrow-${post.id}`}>
|
||||
<tr>
|
||||
<th key={`rowheading-post-${post.id}`} scope="row">
|
||||
@@ -177,8 +154,13 @@ export default function PostTable({
|
||||
headings={headings}
|
||||
editorPost={post}
|
||||
editorControls={editorControls}
|
||||
editorState={editorState}
|
||||
callbacks={callbacks}
|
||||
editorState={state.editor.state}
|
||||
callbacks={{
|
||||
savePost: postActions.savePost,
|
||||
closeEditor: editorControls.closeEditor,
|
||||
refetch: postActions.refetch,
|
||||
uploadAttachment: () => {},
|
||||
}}
|
||||
projects={projects}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
||||
34
src/components/client/input/EntityEditorTextArea.tsx
Normal file
34
src/components/client/input/EntityEditorTextArea.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
'use client'
|
||||
|
||||
import { useRef, MutableRefObject, useLayoutEffect, ChangeEventHandler, useState } from "react";
|
||||
import { StateHook } from '../../../util/types/StateHook';
|
||||
|
||||
export function EntityEditorTextArea({contentHook, className}: {contentHook:StateHook<string>, className:string}){
|
||||
|
||||
let textbox: any = useRef(undefined);
|
||||
|
||||
// Autosize the text area
|
||||
function textAreaAutoSize(
|
||||
textbox: MutableRefObject<HTMLTextAreaElement>
|
||||
): void {
|
||||
if (!textbox.current || !textbox.current.style) return;
|
||||
textbox.current.style.height = "fit-content";
|
||||
textbox.current.style.height = `${textbox.current.scrollHeight}px`;
|
||||
}
|
||||
useLayoutEffect(() => textAreaAutoSize(textbox));
|
||||
|
||||
// Handle user input on the text area by updating state and autosizing the textfield
|
||||
const onTextAreaChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {
|
||||
contentHook?.setState(e.target.value); // Update State
|
||||
textAreaAutoSize(textbox); // Autosize the text area
|
||||
};
|
||||
|
||||
return <textarea
|
||||
key="input-content"
|
||||
onChange={onTextAreaChange}
|
||||
ref={textbox}
|
||||
value={contentHook?.state}
|
||||
style={{ height: "100%" }}
|
||||
className={className}
|
||||
/>
|
||||
}
|
||||
Reference in New Issue
Block a user