make delete non destructive for stories and pubs
display genre badges fitler rows and columns
This commit is contained in:
		
							parent
							
								
									a2a91647c1
								
							
						
					
					
						commit
						670bfdc69c
					
				|  | @ -42,6 +42,7 @@ export const getResponses = async () => { | ||||||
| export const requestEdit = async (data,type) => { | export const requestEdit = async (data,type) => { | ||||||
|     try { |     try { | ||||||
|         const res = await API.post(`/${type}/edit`,data) |         const res = await API.post(`/${type}/edit`,data) | ||||||
|  |         console.log(res) | ||||||
|         return res |         return res | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|         console.error(error) |         console.error(error) | ||||||
|  |  | ||||||
|  | @ -3,9 +3,10 @@ import { useState } from "react" | ||||||
| import { renderClassNames } from "../functions/utilities.mjs" | import { renderClassNames } from "../functions/utilities.mjs" | ||||||
| import { DateTime } from "luxon" | import { DateTime } from "luxon" | ||||||
| import { Link } from "react-router-dom" | import { Link } from "react-router-dom" | ||||||
| import { cloneDeep } from "lodash" | import { cloneDeep, forIn } from "lodash" | ||||||
| export default function Table(props) { | export default function Table(props) { | ||||||
|   const filterList = props?.filterList ?? [] |   const filterColumns = props?.filterColumns ?? [] | ||||||
|  |   const filterRows = props?.filterRows ?? [] | ||||||
|   const sort = (data,sortBy) => { |   const sort = (data,sortBy) => { | ||||||
|     const isDate = (str) =>{ |     const isDate = (str) =>{ | ||||||
|         if(str && DateTime.fromFormat(str,'yyyy-MM-dd').isValid){ |         if(str && DateTime.fromFormat(str,'yyyy-MM-dd').isValid){ | ||||||
|  | @ -37,12 +38,22 @@ export default function Table(props) { | ||||||
|   } |   } | ||||||
|   const data = props?.data ? cloneDeep(props?.data) |   const data = props?.data ? cloneDeep(props?.data) | ||||||
|   .map(e=>{ |   .map(e=>{ | ||||||
|     for (const filter of filterList) { |     for(const filter of filterRows){ | ||||||
|  |       if(e[filter.column]===filter.value){ | ||||||
|  |         return null | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     for (const filter of filterColumns) { | ||||||
|       delete e[filter] |       delete e[filter] | ||||||
|     } |     } | ||||||
|  |     if(props?.extraCols){ | ||||||
|  |       for (const col of props.extraCols) { | ||||||
|  |         e[col[0]]=col[1] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|     return e |     return e | ||||||
|   }) : [] |   }) | ||||||
| 
 |   .filter(e=>{return e!==null}) : [] | ||||||
|   if (data.length === 0) { return <p>Nothing to see here...</p> } |   if (data.length === 0) { return <p>Nothing to see here...</p> } | ||||||
| 
 | 
 | ||||||
|   const [sortBy, setSortBy] = useState({ |   const [sortBy, setSortBy] = useState({ | ||||||
|  | @ -94,11 +105,19 @@ export default function Table(props) { | ||||||
|       return <td key={row[key] + rowIndex + colIndex}>{props.children}</td> |       return <td key={row[key] + rowIndex + colIndex}>{props.children}</td> | ||||||
|     } |     } | ||||||
|     const contents = row[key] |     const contents = row[key] | ||||||
|  | 
 | ||||||
|     if (Array.isArray(contents)) { |     if (Array.isArray(contents)) { | ||||||
|  |       const badgeIndex = props?.badges?.findIndex(e=>{return e[0]==key}) | ||||||
|  |       console.log("badgeIndex for key "+key+": "+badgeIndex) | ||||||
|  |       if(badgeIndex>=0){ | ||||||
|  |         const array = contents.map(e=>{return e[props.badges[badgeIndex][1]]}) | ||||||
|  |         console.dir(array) | ||||||
|  |         return <Cell><Badges data={array} setFocus={props.setFocus} /></Cell> | ||||||
|  |       } | ||||||
|       if (typeof contents[0] === 'object') { |       if (typeof contents[0] === 'object') { | ||||||
|         return <Cell><Table data={contents} setFocus={props.setFocus} /></Cell> |         return <Cell><Table data={contents} setFocus={props.setFocus} /></Cell> | ||||||
|       } |       } | ||||||
|       return <Cell><Badges data={contents} setFocus={props.setFocus} /></Cell> |        | ||||||
|     } |     } | ||||||
|   const getOriginalRowByID = (array,row) => { |   const getOriginalRowByID = (array,row) => { | ||||||
|     return array.find(e=>e?.id===row?.id)  |     return array.find(e=>e?.id===row?.id)  | ||||||
|  | @ -111,9 +130,7 @@ export default function Table(props) { | ||||||
|     if (props?.links?.includes(key)) { |     if (props?.links?.includes(key)) { | ||||||
|       return <Cell><a href={contents}>{contents}</a></Cell> |       return <Cell><a href={contents}>{contents}</a></Cell> | ||||||
|     } |     } | ||||||
|     // if (key === "Days Out") { | 
 | ||||||
|     //   return <Cell>{row['Days Out']} </Cell> |  | ||||||
|     // } |  | ||||||
|     return <Cell>{contents}</Cell> |     return <Cell>{contents}</Cell> | ||||||
|   } |   } | ||||||
|   const oddOrEven = (n) => { |   const oddOrEven = (n) => { | ||||||
|  | @ -131,7 +148,6 @@ export default function Table(props) { | ||||||
|       const classNames = [ |       const classNames = [ | ||||||
|         `row ${oddOrEven(rowIndex)} `, |         `row ${oddOrEven(rowIndex)} `, | ||||||
|         isHighlight(props?.highlights, row) ? 'highlight' : "", |         isHighlight(props?.highlights, row) ? 'highlight' : "", | ||||||
|         //row['Query After'] - row['Days Out'] < 0 && row['Responded'] === '-' ? "alert" : "" |  | ||||||
|       ] |       ] | ||||||
|       return <tr key={row.id} className={renderClassNames(classNames)}>{cells}</tr> |       return <tr key={row.id} className={renderClassNames(classNames)}>{cells}</tr> | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8"> | ||||||
|  |   <path d="M0 0v8h7v-4h-4v-4h-3zm4 0v3h3l-3-3zm-3 2h1v1h-1v-1zm0 2h1v1h-1v-1zm0 2h4v1h-4v-1z" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 183 B | 
|  | @ -1,10 +1,10 @@ | ||||||
| import { redirect } from "react-router"; | import { redirect } from "react-router"; | ||||||
| import { requestDelete } from "../APIcalls.mjs"; | import { requestEdit } from "../APIcalls.mjs"; | ||||||
| 
 | 
 | ||||||
| export async function action({request}){ | export async function action({request}){ | ||||||
|     const formData = await request.formData() |     const formData = await request.formData() | ||||||
|     const data = Object.fromEntries(formData) |     const data = Object.fromEntries(formData) | ||||||
|     console.dir(data) |     console.dir(data) | ||||||
|     await requestDelete({id:Number(data.id)},'publication') |     await requestEdit({id:Number(data.id),deleted:1},'publication') | ||||||
|     return redirect("/publications") |     return redirect("/publications") | ||||||
| } | } | ||||||
|  | @ -1,10 +1,15 @@ | ||||||
| import { redirect } from "react-router"; | import { redirect } from "react-router"; | ||||||
| import { requestDelete } from "../APIcalls.mjs"; | import { requestEdit } from "../APIcalls.mjs"; | ||||||
| 
 | 
 | ||||||
| export async function action({request}){ | export async function action({request}){ | ||||||
|     const formData = await request.formData() |     const formData = await request.formData() | ||||||
|     const data = Object.fromEntries(formData) |     let data = Object.fromEntries(formData) | ||||||
|     console.dir(data) |     console.dir(data) | ||||||
|     await requestDelete({id:Number(data.id)},'story') |     data = { | ||||||
|  |         id:Number(data.id), | ||||||
|  |         deleted:1, | ||||||
|  |     } | ||||||
|  |     console.log(data) | ||||||
|  |     await requestEdit(data,'story') | ||||||
|     return redirect("/stories") |     return redirect("/stories") | ||||||
| } | } | ||||||
|  | @ -3,7 +3,7 @@ import Dropdown from "../Components/Dropdown"; | ||||||
| import { useState } from "react"; | import { useState } from "react"; | ||||||
| export default function EditSubmissionRoot (){ | export default function EditSubmissionRoot (){ | ||||||
| const {submissions} = useLoaderData() | const {submissions} = useLoaderData() | ||||||
| const submissionsOptions = submissions?.map(row=>[row.id,row.date_submitted]) | const submissionsOptions = submissions?.map(row=>[row.id,`#${row.id}, submitted: ${row.date_submitted}`]) | ||||||
| const [id,setId]=useState(1) | const [id,setId]=useState(1) | ||||||
| const handleChange = (event) => { | const handleChange = (event) => { | ||||||
|     const value = event.target.value |     const value = event.target.value | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import Table from "../Components/Table"; | ||||||
| import PageHeader from "../Components/PageHeader"; | import PageHeader from "../Components/PageHeader"; | ||||||
| import { submissionsTableOptions } from "./submissions.jsx"; | import { submissionsTableOptions } from "./submissions.jsx"; | ||||||
| 
 | 
 | ||||||
| const { filterList, highlights, clickables } = submissionsTableOptions | const { filterColumns, highlights, clickables } = submissionsTableOptions | ||||||
| export default function Publication() { | export default function Publication() { | ||||||
|     const { publicationId } = useParams() |     const { publicationId } = useParams() | ||||||
|     const { publications } = useLoaderData() |     const { publications } = useLoaderData() | ||||||
|  | @ -19,7 +19,7 @@ export default function Publication() { | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|             <Table data={publicationData.submissions} |             <Table data={publicationData.submissions} | ||||||
|                 filterList={[...filterList, 'publication']} |                 filterColumns={[...filterColumns, 'publication']} | ||||||
|                 highlights={highlights} |                 highlights={highlights} | ||||||
|                 clickables={clickables} |                 clickables={clickables} | ||||||
|                 sortByDefault='date_submitted' |                 sortByDefault='date_submitted' | ||||||
|  |  | ||||||
|  | @ -9,8 +9,12 @@ import PageHeader from "../Components/PageHeader.jsx"; | ||||||
| 
 | 
 | ||||||
| export default function Publications(){ | export default function Publications(){ | ||||||
|     const { publications } = useLoaderData(); |     const { publications } = useLoaderData(); | ||||||
|     const filterList = [ |     const filterColumns = [ | ||||||
|         'submissions' |         'submissions', | ||||||
|  |         'deleted' | ||||||
|  |     ] | ||||||
|  |     const filterRows = [ | ||||||
|  |         {column:'deleted',value:1} | ||||||
|     ] |     ] | ||||||
|     const links = [ |     const links = [ | ||||||
|         'link' |         'link' | ||||||
|  | @ -23,10 +27,11 @@ export default function Publications(){ | ||||||
|         <PageHeader heading="Publications" url="/publication"/> |         <PageHeader heading="Publications" url="/publication"/> | ||||||
|         <Table  |         <Table  | ||||||
|         data={publications}  |         data={publications}  | ||||||
|         filterList={filterList} |         filterColumns={filterColumns} | ||||||
|         links={links} |         links={links} | ||||||
|         clickables={clickables} |         clickables={clickables} | ||||||
|         sortByDefault='title' |         sortByDefault='title' | ||||||
|  |         filterRows={filterRows} | ||||||
|         /> |         /> | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,6 @@ import { getStories, getPublications, getSubmissions } from "../APIcalls.mjs" | ||||||
| import Loader from "../Components/Loader" | import Loader from "../Components/Loader" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| export function Root() { | export function Root() { | ||||||
|   const navigation = useNavigation() |   const navigation = useNavigation() | ||||||
|     return( |     return( | ||||||
|  | @ -11,7 +10,8 @@ export function Root() { | ||||||
|         <div id="container"> |         <div id="container"> | ||||||
|           {navigation==="loading"?<Loader/>:""} |           {navigation==="loading"?<Loader/>:""} | ||||||
|         <div id="sidebar"> |         <div id="sidebar"> | ||||||
|           <h1>Submission <br/> Manager</h1> version 1.0 |           <h1>Submission <br/> Manager</h1>  | ||||||
|  |           version 0.0.0.0.1 | ||||||
|           <ul> |           <ul> | ||||||
|             <li> |             <li> | ||||||
|             <Link to={`stories`}>STORIES</Link> |             <Link to={`stories`}>STORIES</Link> | ||||||
|  |  | ||||||
|  | @ -2,26 +2,36 @@ import { useLoaderData } from "react-router-dom" | ||||||
| import Table from "../Components/Table.jsx"; | import Table from "../Components/Table.jsx"; | ||||||
| import PageHeader from "../Components/PageHeader.jsx"; | import PageHeader from "../Components/PageHeader.jsx"; | ||||||
| import { getStories } from "../APIcalls.mjs"; | import { getStories } from "../APIcalls.mjs"; | ||||||
| 
 | import magGlass from "../assets/magnifying-glass.svg" | ||||||
| 
 | 
 | ||||||
|    |    | ||||||
| 
 | 
 | ||||||
| export default function Stories(){ | export default function Stories(){ | ||||||
|     const { stories } = useLoaderData(); |     const { stories } = useLoaderData(); | ||||||
|     const filterList = [ |     console.dir(stories) | ||||||
|         'submissions' |     const filterColumns = [ | ||||||
|  |         'submissions', | ||||||
|  |         'deleted' | ||||||
|  |     ] | ||||||
|  |     const filterRows = [ | ||||||
|  |         {column:'deleted',value:1} | ||||||
|     ] |     ] | ||||||
|     const clickables = [ |     const clickables = [ | ||||||
|         ['title',(row)=>{return `../../story/${row.id}`}]     |         ['title',(row)=>{return `../../story/${row.id}`}]     | ||||||
|     ] |     ] | ||||||
|  |     const badges = [ | ||||||
|  |         ['genres','name'] | ||||||
|  |     ] | ||||||
|     return( |     return( | ||||||
|         <div id="page-container"> |         <div id="page-container"> | ||||||
|         <PageHeader heading="Stories" url="/story"/> |         <PageHeader heading="Stories" url="/story"/> | ||||||
|         <Table  |         <Table  | ||||||
|         data={stories}  |         data={stories}  | ||||||
|         filterList={filterList}  |         filterColumns={filterColumns}  | ||||||
|         clickables={clickables} |         clickables={clickables} | ||||||
|         sortByDefault='title' |         sortByDefault='title' | ||||||
|  |         filterRows={filterRows} | ||||||
|  |         badges={badges} | ||||||
|         /> |         /> | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import PageHeader from "../Components/PageHeader"; | ||||||
| import { submissionsTableOptions } from "./submissions.jsx"; | import { submissionsTableOptions } from "./submissions.jsx"; | ||||||
| import { useState, useEffect } from "react"; | import { useState, useEffect } from "react"; | ||||||
| 
 | 
 | ||||||
| const { filterList = [...filterList], highlights, clickables } = submissionsTableOptions | const { filterColumns = [...filterColumns], highlights, clickables } = submissionsTableOptions | ||||||
| export default function Story() { | export default function Story() { | ||||||
|   const { storyId } = useParams() |   const { storyId } = useParams() | ||||||
|   const { stories } = useLoaderData() |   const { stories } = useLoaderData() | ||||||
|  | @ -20,7 +20,7 @@ export default function Story() { | ||||||
|         </div> |         </div> | ||||||
|         <Table |         <Table | ||||||
|           data={storyData.submissions} |           data={storyData.submissions} | ||||||
|           filterList={[...filterList, 'story']} |           filterColumns={[...filterColumns, 'story']} | ||||||
|           highlights={highlights} |           highlights={highlights} | ||||||
|           clickables={clickables} |           clickables={clickables} | ||||||
|           sortByDefault='date_submitted' |           sortByDefault='date_submitted' | ||||||
|  |  | ||||||
|  | @ -2,9 +2,10 @@ import { useLoaderData } from "react-router-dom"; | ||||||
| import { getSubmissions } from "../APIcalls.mjs"; | import { getSubmissions } from "../APIcalls.mjs"; | ||||||
| import Table from "../Components/Table"; | import Table from "../Components/Table"; | ||||||
| import PageHeader from "../Components/PageHeader"; | import PageHeader from "../Components/PageHeader"; | ||||||
|  | import edit from '../assets/pencil.svg' | ||||||
| 
 | 
 | ||||||
| export const submissionsTableOptions = { | export const submissionsTableOptions = { | ||||||
|      filterList : [ |      filterColumns : [ | ||||||
|         'response_id', |         'response_id', | ||||||
|         'pub_id', |         'pub_id', | ||||||
|         'story_id' |         'story_id' | ||||||
|  | @ -21,7 +22,7 @@ export const submissionsTableOptions = { | ||||||
| 
 | 
 | ||||||
| export function Submissions(){ | export function Submissions(){ | ||||||
|     const { submissions } = useLoaderData(); |     const { submissions } = useLoaderData(); | ||||||
|     const filterList = [ |     const filterColumns = [ | ||||||
|         'response_id', |         'response_id', | ||||||
|         'pub_id', |         'pub_id', | ||||||
|         'story_id' |         'story_id' | ||||||
|  | @ -33,7 +34,11 @@ export function Submissions(){ | ||||||
|         ['story',(row)=>{ |         ['story',(row)=>{ | ||||||
|             return `../../story/${row.story_id}`}], |             return `../../story/${row.story_id}`}], | ||||||
|         ['publication',(row)=>{return `../../publication/${row.pub_id}`}], |         ['publication',(row)=>{return `../../publication/${row.pub_id}`}], | ||||||
|         ['id',(row)=>{return `../../submission/${row.id}/edit`}]       |         ['edit',(row)=>{return `../../submission/${row.id}/edit`}]       | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     const extraCols = [ | ||||||
|  |         ['edit', <img src={edit} width="100%" style={{margin:"auto"}}/>] | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -43,10 +48,11 @@ export function Submissions(){ | ||||||
|         <PageHeader heading="Submissions" url="/submission"/> |         <PageHeader heading="Submissions" url="/submission"/> | ||||||
|         <Table  |         <Table  | ||||||
|         data={submissions}  |         data={submissions}  | ||||||
|         filterList={filterList}  |         filterColumns={filterColumns}  | ||||||
|         highlights={highlights}  |         highlights={highlights}  | ||||||
|         sortByDefault="date_submitted" |         sortByDefault="date_submitted" | ||||||
|         clickables={clickables} |         clickables={clickables} | ||||||
|  |         extraCols={extraCols} | ||||||
|         /> |         /> | ||||||
|         </div> |         </div> | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
|     width: 5rem; |     width: 5rem; | ||||||
|     height: 5rem; |     height: 5rem; | ||||||
|     margin: 1rem; |     margin: 1rem; | ||||||
|     filter: invert(83%) sepia(12%) saturate(387%) hue-rotate(129deg) brightness(89%) contrast(89%); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #page-header h1 { | #page-header h1 { | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ | ||||||
| #sidebar h1{ | #sidebar h1{ | ||||||
|     text-shadow: var(--text-shadow-dark); |     text-shadow: var(--text-shadow-dark); | ||||||
|     font-size:4.5rem; |     font-size:4.5rem; | ||||||
|  |     line-height: 1em; | ||||||
|  |     margin-bottom: 1rem; | ||||||
| } | } | ||||||
| #sidebar a:hover{ | #sidebar a:hover{ | ||||||
|     text-shadow: |     text-shadow: | ||||||
|  |  | ||||||
|  | @ -73,6 +73,9 @@ html { | ||||||
|     cursor:pointer; |     cursor:pointer; | ||||||
|   } |   } | ||||||
|   |   | ||||||
|  |   img{ | ||||||
|  |     filter: invert(83%) sepia(12%) saturate(500%) hue-rotate(129deg) brightness(60%) contrast(89%); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   h1{ |   h1{ | ||||||
|     font-size: 4rem; |     font-size: 4rem; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue