|
|
@ -11,7 +11,10 @@ import { queryTags } from '../../../lib/query/Backend'; |
|
|
|
var _ = require('lodash'); |
|
|
|
var _ = require('lodash'); |
|
|
|
|
|
|
|
|
|
|
|
export interface ManageTagsWindowState extends WindowState { |
|
|
|
export interface ManageTagsWindowState extends WindowState { |
|
|
|
fetchedTags: Record<number, any> | null, |
|
|
|
// Tags are indexed by a string ID. This can be a stringified MuDBase ID integer,
|
|
|
|
|
|
|
|
// or a UID for tags which only exist in the front-end and haven't been committed
|
|
|
|
|
|
|
|
// to the database.
|
|
|
|
|
|
|
|
fetchedTags: Record<string, any> | null, |
|
|
|
pendingChanges: TagChange[], |
|
|
|
pendingChanges: TagChange[], |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -37,7 +40,7 @@ export function ManageTagsWindowReducer(state: ManageTagsWindowState, action: an |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function organiseTags(allTags: Record<number, any>, fromId: number | null): any[] { |
|
|
|
export function organiseTags(allTags: Record<string, any>, fromId: string | null): any[] { |
|
|
|
const base = Object.values(allTags).filter((tag: any) => { |
|
|
|
const base = Object.values(allTags).filter((tag: any) => { |
|
|
|
var par: any = ("proposedParent" in tag) ? tag.proposedParent : tag.parentId; |
|
|
|
var par: any = ("proposedParent" in tag) ? tag.proposedParent : tag.parentId; |
|
|
|
|
|
|
|
|
|
|
@ -55,14 +58,21 @@ export function organiseTags(allTags: Record<number, any>, fromId: number | null |
|
|
|
|
|
|
|
|
|
|
|
export async function getAllTags() { |
|
|
|
export async function getAllTags() { |
|
|
|
return (async () => { |
|
|
|
return (async () => { |
|
|
|
var retval: Record<number, any> = {}; |
|
|
|
var retval: Record<string, any> = {}; |
|
|
|
const tags = await queryTags({ |
|
|
|
const tags = await queryTags({ |
|
|
|
query: undefined, |
|
|
|
query: undefined, |
|
|
|
offset: 0, |
|
|
|
offset: 0, |
|
|
|
limit: -1, |
|
|
|
limit: -1, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
// Convert numeric IDs to string IDs because that is
|
|
|
|
|
|
|
|
// what we work with within this component.
|
|
|
|
tags.forEach((tag: any) => { |
|
|
|
tags.forEach((tag: any) => { |
|
|
|
retval[tag.tagId] = tag; |
|
|
|
retval[tag.tagId.toString()] = { |
|
|
|
|
|
|
|
...tag, |
|
|
|
|
|
|
|
tagId: tag.tagId && tag.tagId.toString(), |
|
|
|
|
|
|
|
parentId: tag.parentId && tag.parentId.toString(), |
|
|
|
|
|
|
|
childIds: tag.childIds && tag.childIds.map((c: number) => c.toString()), |
|
|
|
|
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
return retval; |
|
|
|
return retval; |
|
|
|
})(); |
|
|
|
})(); |
|
|
@ -156,7 +166,7 @@ export function SingleTag(props: { |
|
|
|
] |
|
|
|
] |
|
|
|
}) |
|
|
|
}) |
|
|
|
}} |
|
|
|
}} |
|
|
|
onMove={(to: number | null) => { |
|
|
|
onMove={(to: string | null) => { |
|
|
|
props.dispatch({ |
|
|
|
props.dispatch({ |
|
|
|
type: ManageTagsWindowActions.SetPendingChanges, |
|
|
|
type: ManageTagsWindowActions.SetPendingChanges, |
|
|
|
value: [ |
|
|
|
value: [ |
|
|
@ -168,6 +178,9 @@ export function SingleTag(props: { |
|
|
|
} |
|
|
|
} |
|
|
|
] |
|
|
|
] |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
onCreateChild={(name: string) => { |
|
|
|
|
|
|
|
|
|
|
|
}} |
|
|
|
}} |
|
|
|
tag={tag} |
|
|
|
tag={tag} |
|
|
|
changedTags={props.changedTags} |
|
|
|
changedTags={props.changedTags} |
|
|
@ -175,10 +188,10 @@ export function SingleTag(props: { |
|
|
|
</> |
|
|
|
</> |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function annotateTagsWithChanges(tags: Record<number, any>, changes: TagChange[]) { |
|
|
|
function annotateTagsWithChanges(tags: Record<string, any>, changes: TagChange[]) { |
|
|
|
var retval = _.cloneDeep(tags); |
|
|
|
var retval: Record<string, any> = tags; |
|
|
|
|
|
|
|
|
|
|
|
const applyDelete = (id: number) => { |
|
|
|
const applyDelete = (id: string) => { |
|
|
|
retval[id].proposeDelete = true; |
|
|
|
retval[id].proposeDelete = true; |
|
|
|
Object.values(tags).filter((t: any) => t.parentId === id) |
|
|
|
Object.values(tags).filter((t: any) => t.parentId === id) |
|
|
|
.forEach((child: any) => applyDelete(child.tagId)); |
|
|
|
.forEach((child: any) => applyDelete(child.tagId)); |
|
|
@ -202,10 +215,10 @@ function annotateTagsWithChanges(tags: Record<number, any>, changes: TagChange[] |
|
|
|
return retval; |
|
|
|
return retval; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function applyTagsChanges(tags: Record<number, any>, changes: TagChange[]) { |
|
|
|
function applyTagsChanges(tags: Record<string, any>, changes: TagChange[]) { |
|
|
|
var retval = _.cloneDeep(tags); |
|
|
|
var retval = _.cloneDeep(tags); |
|
|
|
|
|
|
|
|
|
|
|
const applyDelete = (id: number) => { |
|
|
|
const applyDelete = (id: string) => { |
|
|
|
Object.values(tags).filter((t: any) => t.parentId === id) |
|
|
|
Object.values(tags).filter((t: any) => t.parentId === id) |
|
|
|
.forEach((child: any) => applyDelete(child.tagId)); |
|
|
|
.forEach((child: any) => applyDelete(child.tagId)); |
|
|
|
delete retval[id].proposeDelete; |
|
|
|
delete retval[id].proposeDelete; |
|
|
@ -230,13 +243,11 @@ function applyTagsChanges(tags: Record<number, any>, changes: TagChange[]) { |
|
|
|
return retval; |
|
|
|
return retval; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export interface IProps { |
|
|
|
export default function ManageTagsWindow(props: { |
|
|
|
state: ManageTagsWindowState, |
|
|
|
state: ManageTagsWindowState, |
|
|
|
dispatch: (action: any) => void, |
|
|
|
dispatch: (action: any) => void, |
|
|
|
mainDispatch: (action: any) => void, |
|
|
|
mainDispatch: (action: any) => void, |
|
|
|
} |
|
|
|
}) { |
|
|
|
|
|
|
|
|
|
|
|
export default function ManageTagsWindow(props: IProps) { |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
if (props.state.fetchedTags !== null) { |
|
|
|
if (props.state.fetchedTags !== null) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -285,6 +296,7 @@ export default function ManageTagsWindow(props: IProps) { |
|
|
|
value: [], |
|
|
|
value: [], |
|
|
|
})} |
|
|
|
})} |
|
|
|
onSave={() => { }} |
|
|
|
onSave={() => { }} |
|
|
|
|
|
|
|
getTagDetails={(id: string) => tagsWithChanges[id]} |
|
|
|
/> |
|
|
|
/> |
|
|
|
</Box>} |
|
|
|
</Box>} |
|
|
|
<Box |
|
|
|
<Box |
|
|
|