Skip to content

Commit

Permalink
Switched the KnowledgeDomain and Level context over to the string-map…
Browse files Browse the repository at this point in the history
…-within-selective-context hook.
  • Loading branch information
buchananwill committed Apr 14, 2024
1 parent d517e35 commit 3ee5df0
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 105 deletions.
16 changes: 12 additions & 4 deletions app/graphing/components/node-detail-wrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import React, { Fragment, PropsWithChildren } from 'react';
import React, { FC, Fragment, PropsWithChildren } from 'react';
import { Disclosure } from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/20/solid';
import { DataNode } from '../../api/zod-mods';
Expand All @@ -12,12 +12,18 @@ import { StarIcon as StarIconOutline } from '@heroicons/react/24/outline';
import { StarIcon } from '@heroicons/react/24/solid';
import { HasNumberIdDto } from '../../api/dtos/HasNumberIdDtoSchema';
import { Button } from '@nextui-org/button';
import { NodeDetailsUiComponentProps } from '../graph-types/work-task-types/work-task-type-dto-details';

export function NodeDetailWrapper<T extends HasNumberIdDto>({
label,
children,
node
}: { label: string; node: DataNode<T> } & PropsWithChildren) {
node,
detailsUiComponent: Details
}: {
label: string;
node: DataNode<T>;
detailsUiComponent?: FC<NodeDetailsUiComponentProps<T>>;
} & PropsWithChildren) {
const { dispatch } = useNodeInteractionContext();
const isSelected = useNodeSelectedListener(node.id);

Expand Down Expand Up @@ -50,7 +56,9 @@ export function NodeDetailWrapper<T extends HasNumberIdDto>({
</SelectionOutline>
</div>

<Disclosure.Panel>{children}</Disclosure.Panel>
<Disclosure.Panel>
{Details && <Details node={node} />}
</Disclosure.Panel>
</>
)}
</Disclosure>
Expand Down
12 changes: 7 additions & 5 deletions app/graphing/components/node-details.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react';
import React, { FC } from 'react';
import { NodeDetailWrapper } from './node-detail-wrapper';
import { NodePayload } from '../force-graph-page';
import { HasNumberIdDto } from '../../api/dtos/HasNumberIdDtoSchema';
import { NodeDetailsUiComponentProps } from '../graph-types/work-task-types/work-task-type-dto-details';

export default function NodeDetails<T extends HasNumberIdDto>({
nodeDetailElements,
labels
labels,
detailsUiComponent
}: {
nodeDetailElements: NodePayload<T>[];
labels: string[];
detailsUiComponent?: FC<NodeDetailsUiComponentProps<T>>;
}) {
return (
<div>
Expand All @@ -17,9 +20,8 @@ export default function NodeDetails<T extends HasNumberIdDto>({
key={`${index}-${labels[index]}`}
label={`${labels[index]}`}
node={detailElement.node}
>
{detailElement.payload}
</NodeDetailWrapper>
detailsUiComponent={detailsUiComponent}
/>
))}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion app/graphing/force-graph-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ShowNodeEditing } from './show-node-editing';

export interface NodePayload<T extends HasNumberIdDto> {
node: DataNode<T>;
payload: React.JSX.Element;
payload?: React.JSX.Element;
}
export default function ForceGraphPage<T extends HasNumberIdDto>({
dataGraph: graphDto,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { StringMap } from '../../../contexts/string-map-context/string-map-reducer';
import { ColumnOne, ColumnsTwoToFour } from './rename-work-task-type';
import { Listbox } from '@headlessui/react';
import {
NodeDetailsListBoxButton,
NodeDetailsListBoxOption,
NodeDetailsListBoxOptions
} from '../organization/curriculum-delivery-details';
import React, { Fragment } from 'react';
import { isNotUndefined } from '../../../api/main';

export function AssignItemFromObjectEntries<T>({
itemDescriptor,
currentAssignment,
onChange,
optionsMap,
labelAccessor,
idAccessor
}: {
itemDescriptor: string;
currentAssignment: string;
onChange: (value: string) => void;
optionsMap: StringMap<T>;
labelAccessor: (item: T) => string;
idAccessor: (item: T) => string;
}) {
console.log(optionsMap);
return (
<>
<ColumnOne>{itemDescriptor}</ColumnOne>
<ColumnsTwoToFour>
<Listbox value={currentAssignment} onChange={onChange}>
<Listbox.Button as={NodeDetailsListBoxButton}>
{isNotUndefined(optionsMap[currentAssignment])
? labelAccessor(optionsMap[currentAssignment])
: 'Unassigned'}
</Listbox.Button>
<Listbox.Options as={NodeDetailsListBoxOptions} optionsWidth={'w-60'}>
{Object.values(optionsMap)
.filter(isNotUndefined)
.map((option) => (
<Listbox.Option
value={idAccessor(option)}
key={`${itemDescriptor}-${idAccessor(option)}`}
as={Fragment}
>
{({ selected, active }) => (
<NodeDetailsListBoxOption
selected={selected}
active={active}
>
{labelAccessor(option)}
</NodeDetailsListBoxOption>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
</ColumnsTwoToFour>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import React from 'react';
import WorkTaskTypeDtoDetails from './work-task-type-dto-details';
import NodeDetails from '../../components/node-details';
import { putGraph } from '../../../api/READ-ONLY-generated-actions/WorkTaskType';
import { useStringMapContextController } from './use-string-map-context-controller';

const graphUpdater = getGraphUpdaterWithNameDeDuplication(putGraph);

const ListenerKey = `lessonTypeHierarchyGraph`;

export function LessonTypeHierarchyGraph() {
const { nodes, nodesRef, linksRef } = useNodeAndLinkRefs<WorkTaskTypeDto>();

Expand All @@ -26,6 +29,16 @@ export function LessonTypeHierarchyGraph() {
CloneFunctionWrapper,
graphUpdater
);
const { currentState: stringMapKd } = useStringMapContextController(
'knowledgeDomain',
ListenerKey
);
const { currentState: stringMapKl } = useStringMapContextController(
'knowledgeLevel',
ListenerKey
);

console.log(stringMapKd);

nodes.forEach((n: DataNode<WorkTaskTypeDto>) => {
lessonTypeList.push(n.data.name);
Expand All @@ -38,13 +51,7 @@ export function LessonTypeHierarchyGraph() {
const nodeDetailElements: NodePayload<WorkTaskTypeDto>[] =
nodesRef.current.map((node) => {
return {
node: node,
payload: (
<WorkTaskTypeDtoDetails
key={`delivery-details-${node.data.id}`}
node={node}
></WorkTaskTypeDtoDetails>
)
node: node
};
});

Expand All @@ -59,6 +66,7 @@ export function LessonTypeHierarchyGraph() {
<NodeDetails
nodeDetailElements={nodeDetailElements}
labels={lessonTypeList}
detailsUiComponent={WorkTaskTypeDtoDetails}
/>
</NodeLinkRefWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
useSelectiveContextAnyController,
useSelectiveContextGlobalListener
} from '../../../selective-context/components/global/selective-context-manager-global';
import {
getIdListContextKey,
getNameSpacedKey
} from '../../../selective-context/components/controllers/dto-id-list-controller';
import { useSelectiveContextListenerReadAll } from '../../../selective-context/components/base/generic-selective-context-creator';
import { SelectiveContextGlobal } from '../../../selective-context/components/global/selective-context-creator-global';
import { useMemo } from 'react';
import { getEntityNamespaceContextKey } from '../../../selective-context/hooks/dtoStores/use-dto-store';
import { EmptyArray, isNotUndefined } from '../../../api/main';
import { StringMap } from '../../../contexts/string-map-context/string-map-reducer';
import { KnowledgeDomainDto } from '../../../api/dtos/KnowledgeDomainDtoSchema';

export function useStringMapContextController<T, U extends string | number>(
entityName: string,
listenerKey: string
) {
const { currentState: idList } = useSelectiveContextGlobalListener<U[]>({
contextKey: getIdListContextKey(entityName),
listenerKey: listenerKey,
initialValue: EmptyArray
});

const selectiveContextReadAll = useSelectiveContextListenerReadAll(
SelectiveContextGlobal
);

const stringMap = useMemo(() => {
return idList
.map((id) =>
selectiveContextReadAll(getEntityNamespaceContextKey(entityName, id))
)
.filter(isNotUndefined)
.reduce((prev, curr) => {
const next = { ...prev };
next[curr.id] = curr;
return next;
}, {});
}, [idList, selectiveContextReadAll, entityName]);

const nameSpacedKey = getNameSpacedKey(entityName, 'stringMap');
console.log(nameSpacedKey, stringMap);
return useSelectiveContextAnyController<StringMap<T>>({
contextKey: nameSpacedKey,
listenerKey: listenerKey,
initialValue: stringMap
});
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,57 @@
'use client';
import { DataNode } from '../../../api/zod-mods';
import React, { Fragment } from 'react';
import React from 'react';
import { WorkTaskTypeDto } from '../../../api/dtos/WorkTaskTypeDtoSchema';
import {
NodeDetailsListBoxButton,
NodeDetailsListBoxOption,
NodeDetailsListBoxOptions
} from '../organization/curriculum-delivery-details';
import { useServiceCategoryContext } from '../../../work-types/lessons/use-service-category-context';
import { Listbox } from '@headlessui/react';
import { StringMap } from '../../../contexts/string-map-context/string-map-reducer';
import { useDirectSimRefEditsDispatch } from '../../editing/functions/use-graph-edit-button-hooks';
import {
ColumnOne,
ColumnsTwoToFour,
RenameWorkTaskType,
WorkTaskTypeDtoDetailsListenerKey
} from './rename-work-task-type';
import { useSelectiveContextGlobalListener } from '../../../selective-context/components/global/selective-context-manager-global';
import { getNameSpacedKey } from '../../../selective-context/components/controllers/dto-id-list-controller';
import { KnowledgeDomainDto } from '../../../api/dtos/KnowledgeDomainDtoSchema';
import { KnowledgeLevelDto } from '../../../api/dtos/KnowledgeLevelDtoSchema';
import { AssignItemFromObjectEntries } from './assign-item-from-object-entries';
import { HasNumberIdDto } from '../../../api/dtos/HasNumberIdDtoSchema';
import { ObjectPlaceholder } from '../../../api/main';

export interface NodeDetailsUiComponentProps<T extends HasNumberIdDto> {
node: DataNode<T>;
}

export default function WorkTaskTypeDtoDetails({
node
}: {
node: DataNode<WorkTaskTypeDto>;
}) {
}: NodeDetailsUiComponentProps<WorkTaskTypeDto>) {
const { id, data } = node;
const { knowledgeDomainId, knowledgeLevelId } = data;

const { domainMap, levelMap } = useServiceCategoryContext();
const { currentState: kDomainMap } = useSelectiveContextGlobalListener<
StringMap<KnowledgeDomainDto>
>({
contextKey: getNameSpacedKey('knowledgeDomain', 'stringMap'),
listenerKey: `workTaskType:${node.id}:details`,
initialValue: ObjectPlaceholder
});
const { currentState: kLevelMap } = useSelectiveContextGlobalListener<
StringMap<KnowledgeLevelDto>
>({
contextKey: getNameSpacedKey('knowledgeLevel', 'stringMap'),
listenerKey: `workTaskType:${node.id}:details`,
initialValue: ObjectPlaceholder
});

console.log(kLevelMap, kDomainMap, node);

console.log(knowledgeDomainId, knowledgeLevelId);

const editListenerKey = `${WorkTaskTypeDtoDetailsListenerKey}-${id}`;

const { incrementSimVersion, nodeListRef } =
useDirectSimRefEditsDispatch<WorkTaskTypeDto>(editListenerKey);

const handleKnowledgeDomainChange = (domainId: string) => {
const updatedDomain = domainMap[domainId];
const updatedDomain: KnowledgeDomainDto = kDomainMap[domainId];
if (nodeListRef === null) return;
const find = nodeListRef.current.find((n) => n.id === id);
if (find === undefined) return;
Expand All @@ -51,65 +69,21 @@ export default function WorkTaskTypeDtoDetails({
<RenameWorkTaskType node={node} />
<AssignItemFromObjectEntries
itemDescriptor={'Subject'}
currentAssignment={knowledgeDomainId.toString()}
currentAssignment={`${knowledgeDomainId}`}
onChange={handleKnowledgeDomainChange}
optionsMap={domainMap}
optionsMap={kDomainMap}
labelAccessor={(kd) => kd.name}
idAccessor={(kd) => kd.id.toString()}
/>
<AssignItemFromObjectEntries
itemDescriptor={'Year'}
currentAssignment={knowledgeLevelId.toString()}
currentAssignment={`${knowledgeLevelId}`}
onChange={handleKnowledgeLevelChange}
optionsMap={levelMap}
optionsMap={kLevelMap}
labelAccessor={(kl) => kl.name}
idAccessor={(kl) => kl.id.toString()}
/>
</div>
</div>
);
}

function AssignItemFromObjectEntries<T>({
itemDescriptor,
currentAssignment,
onChange,
optionsMap,
labelAccessor,
idAccessor
}: {
itemDescriptor: string;
currentAssignment: string;
onChange: (value: string) => void;
optionsMap: StringMap<T>;
labelAccessor: (item: T) => string;
idAccessor: (item: T) => string;
}) {
return (
<>
<ColumnOne>{itemDescriptor}</ColumnOne>
<ColumnsTwoToFour>
<Listbox value={currentAssignment} onChange={onChange}>
<Listbox.Button as={NodeDetailsListBoxButton}>
{labelAccessor(optionsMap[currentAssignment])}
</Listbox.Button>
<Listbox.Options as={NodeDetailsListBoxOptions} optionsWidth={'w-60'}>
{Object.values(optionsMap).map((option) => (
<Listbox.Option
value={idAccessor(option)}
key={`${itemDescriptor}-${idAccessor(option)}`}
as={Fragment}
>
{({ selected, active }) => (
<NodeDetailsListBoxOption selected={selected} active={active}>
{labelAccessor(option)}
</NodeDetailsListBoxOption>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
</ColumnsTwoToFour>
</>
);
}
Loading

0 comments on commit 3ee5df0

Please sign in to comment.