Skip to content

Commit

Permalink
wip show type
Browse files Browse the repository at this point in the history
Signed-off-by: Drew Hess <src@drewhess.com>
  • Loading branch information
dhess committed Jun 8, 2023
1 parent 3c6b7ce commit a824592
Show file tree
Hide file tree
Showing 16 changed files with 301 additions and 11 deletions.
2 changes: 1 addition & 1 deletion argocd/base/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ spec:
# Note: use the *dev* version of the package here, so that
# PRs can deploy `primer-service` container images that have
# not yet been merged to `primer` `main`.
image: ghcr.io/hackworthltd/primer-service-dev:git-248899f37edb88f2b00945097ff075c5fc0dfef6
image: ghcr.io/hackworthltd/primer-service-dev:git-fdd5b31b4c2a0053447f303efbbc1793d9bbb10f
ports:
- containerPort: 8081
env:
Expand Down
8 changes: 4 additions & 4 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Note: don't override any of primer's Nix flake inputs, or else
# we won't hit its binary cache.
primer.url = github:hackworthltd/primer/248899f37edb88f2b00945097ff075c5fc0dfef6;
primer.url = github:hackworthltd/primer/fdd5b31b4c2a0053447f303efbbc1793d9bbb10f;

flake-parts.url = "github:hercules-ci/flake-parts";
};
Expand Down
21 changes: 20 additions & 1 deletion src/Edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import {
Level,
useUndo,
useRedo,
useGetTypeOrKind,
TypeOrKind,
} from "./primer-api";
import {
defaultTreeReactFlowProps,
Expand Down Expand Up @@ -82,9 +84,22 @@ const Edit = (): JSX.Element => {

const AppProg = (p: { sessionId: string; initialProg: Prog }): JSX.Element => {
const [prog, setProg0] = useState<Prog>(p.initialProg);
const [selection, setSelection] = useState<Selection | undefined>(
const [selection, setSelection0] = useState<Selection | undefined>(
prog.selection
);
const getTypeOrKind = useGetTypeOrKind();
const [selectionTypeOrKind, setSelectionTypeOrKind] = useState<
TypeOrKind | undefined
>();
const setSelection = (s: Selection | undefined) => {
s
? getTypeOrKind
.mutateAsync({ sessionId: p.sessionId, data: s })
.then(setSelectionTypeOrKind)
.catch((_) => setSelectionTypeOrKind(undefined))
: setSelectionTypeOrKind(undefined);
setSelection0(s);
};
const setProg = (prog: Prog) => {
setProg0(prog);
setSelection(prog.selection);
Expand All @@ -108,6 +123,7 @@ const AppProg = (p: { sessionId: string; initialProg: Prog }): JSX.Element => {
return (
<AppNoError
sessionId={p.sessionId}
selectionTypeOrKind={selectionTypeOrKind}
module={module}
imports={importedModules}
selection={selection}
Expand Down Expand Up @@ -169,6 +185,7 @@ const AppNoError = ({
module: Module;
imports: Module[];
selection: Selection | undefined;
selectionTypeOrKind: TypeOrKind | undefined;
setSelection: (s: Selection) => void;
setProg: (p: Prog) => void;
undoAvailable: boolean;
Expand Down Expand Up @@ -297,6 +314,7 @@ const AppNoError = ({
</div>

<PictureInPicture
initialTab="Info"
level={level}
// Note: these offsets are rather arbitrary.
initialPosition={{ x: 10, y: 10 }}
Expand All @@ -306,6 +324,7 @@ const AppNoError = ({
...(evalResult.isSuccess ? { result: evalResult.data } : {}),
}}
defs={defs}
typeOrKind={p.selectionTypeOrKind}
/>
</TreeReactFlow>
</ReactFlowProvider>
Expand Down
45 changes: 41 additions & 4 deletions src/components/PictureInPicture/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { InformationCircleIcon } from "@heroicons/react/24/outline";
import classNames from "classnames";
import { useRef, useState } from "react";
import { useDraggable, DragOptions } from "@neodrag/react";
import type { EvalFullProps } from "@/components/EvalFull";
import { EvalFull } from "@/components";
import type { SelectionInfoProps } from "@/components/SelectionInfo";
import { EvalFull, SelectionInfo } from "@/components";

export type PictureInPictureTab = "Evaluation" | "Info";

export type PictureInPictureProps = {
initialTab: PictureInPictureTab;
initialPosition: { x: number; y: number };
} & EvalFullProps;
} & EvalFullProps &
SelectionInfoProps;

export const PictureInPicture = (p: PictureInPictureProps): JSX.Element => {
const [currentTab, switchTab] = useState(p.initialTab);
const [touchDragging, setTouchDragging] = useState(false);

const draggableRef = useRef(null);
Expand All @@ -25,6 +32,21 @@ export const PictureInPicture = (p: PictureInPictureProps): JSX.Element => {
};
useDraggable(draggableRef, options);

const tab = (tab: PictureInPictureTab, element: JSX.Element): JSX.Element => (
<button
key={tab}
className={classNames(
"flex",
tab == currentTab
? "text-blue-primary border-y-8 border-t-transparent"
: "hover:text-blue-secondary hover:border-y-8 hover:border-t-transparent"
)}
onClick={(_) => switchTab(tab)}
>
<div className="flex w-full flex-col self-center">{element}</div>
</button>
);

return (
<div
ref={draggableRef}
Expand All @@ -34,10 +56,25 @@ export const PictureInPicture = (p: PictureInPictureProps): JSX.Element => {
)}
>
<div className="neodrag-react-handle mx-2 mt-2 block select-none text-sm font-medium leading-6 text-blue-primary">
Evaluate
<div className="grid h-20 grid-cols-2 text-grey-secondary">
{tab(
"Evaluation",
<div className="text-center text-base font-bold lg:text-lg">
Evaluation
</div>
)}
{tab("Info", <InformationCircleIcon className="h-8" />)}
</div>
</div>
<div className="grow">
<EvalFull {...p} />
{(() => {
switch (currentTab) {
case "Evaluation":
return <EvalFull {...p} />;
case "Info":
return <SelectionInfo {...p} />;
}
})()}
</div>
</div>
);
Expand Down
49 changes: 49 additions & 0 deletions src/components/SelectionInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { NodeChange, ReactFlowProvider, useReactFlow } from "reactflow";
import { Level, TypeOrKind } from "@/primer-api";
import { TreeReactFlowOne } from "@/components";
import { defaultTreeReactFlowProps } from "../TreeReactFlow";

export type SelectionInfoProps = {
typeOrKind: TypeOrKind | undefined;
level: Level;
};

const TypeOrKindTree = (p: { typeOrKind: TypeOrKind; level: Level }) => {
const padding = 1.0;
const { fitView } = useReactFlow();
const onNodesChange = (_: NodeChange[]) => {
fitView({ padding });
};

return (
<TreeReactFlowOne
{...defaultTreeReactFlowProps}
tree={p.typeOrKind.contents}
level={p.level}
zoomBarProps={{ padding }}
onNodesChange={onNodesChange}
fitViewOptions={{ padding }}
/>
);
};

export const SelectionInfo = ({
typeOrKind,
level,
}: SelectionInfoProps): JSX.Element => {
return (
<div className="flex h-full flex-col overflow-auto">
{typeOrKind && (
<>
<div className="grow">
<ReactFlowProvider>
<TypeOrKindTree typeOrKind={typeOrKind} level={level} />
</ReactFlowProvider>
</div>
</>
)}
</div>
);
};

export default SelectionInfo;
48 changes: 48 additions & 0 deletions src/components/TreeReactFlow/Flavor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ export const flavorClasses = (flavor: NodeFlavor): string => {
"hover:ring-green-primary",
commonHoverClasses
);
case "KHole":
return classNames(
"border-red-tertiary ring-red-tertiary bg-white-primary",
"hover:ring-red-tertiary",
commonHoverClasses
);
case "KType":
return classNames(
"border-grey-secondary ring-grey-secondary bg-grey-secondary",
"hover:ring-grey-secondary",
commonHoverClasses
);
case "KFun":
return classNames(
"border-grey-secondary ring-grey-secondary bg-grey-secondary",
"hover:ring-grey-secondary",
commonHoverClasses
);
case "Lam":
return classNames(
"border-blue-primary ring-blue-primary bg-white-primary",
Expand Down Expand Up @@ -200,6 +218,12 @@ export const flavorContentClasses = (
return "text-white-primary";
case "Con":
return "text-blue-primary";
case "KHole":
return "text-blue-primary";
case "KType":
return "text-blue-primary";
case "KFun":
return "text-blue-primary";
case "Lam":
return "text-blue-primary";
case "LAM":
Expand Down Expand Up @@ -270,6 +294,12 @@ export const flavorLabelClasses = (flavor: NodeFlavor): string => {
return "font-code bg-black-primary border-black-primary text-white-primary";
case "GlobalVar":
return "bg-blue-quaternary border-blue-quaternary text-white-primary";
case "KHole":
return "font-code bg-red-tertiary border-red-tertiary text-white-primary";
case "KType":
return "font-code bg-grey-secondary bg-grey-secondary text-white-primary";
case "KFun":
return "font-code bg-grey-secondary bg-grey-secondary text-white-primary";
case "LocalVar":
return "bg-blue-quaternary border-blue-quaternary text-white-primary";
case "Let":
Expand Down Expand Up @@ -327,6 +357,12 @@ export const flavorEdgeClasses = (flavor: NodeFlavor): string => {
return "stroke-yellow-secondary";
case "Con":
return "stroke-green-primary";
case "KHole":
return "stroke-grey-seconary";
case "KType":
return "stroke-grey-seconary";
case "KFun":
return "stroke-grey-seconary";
case "Lam":
return "stroke-blue-primary";
case "LAM":
Expand Down Expand Up @@ -436,6 +472,12 @@ export const flavorLabel = (flavor: NodeFlavor): string => {
return "🤷🏽‍♀️";
case "PatternBind":
return "Var";
case "KType":
return "*";
case "KHole":
return "?";
case "KFun":
return "*→*";
}
};

Expand Down Expand Up @@ -465,6 +507,12 @@ export const noBodyFlavorContents = (flavor: NodeFlavorNoBody): string => {
return "{?}";
case "PatternWildcard":
return "🤷🏽‍♀️";
case "KType":
return "type";
case "KHole":
return "?";
case "KFun":
return "type constructor";
}
};

Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as Branding } from "./Branding";
export { default as PictureInPicture } from "./PictureInPicture";
export { default as SearchBar } from "./SearchBar";
export { default as SelectMenu } from "./SelectMenu";
export { default as SelectionInfo } from "./SelectionInfo";
export { default as SessionList } from "./SessionList";
export { default as SessionNameModal } from "./SessionNameModal";
export { default as SessionPreview } from "./SessionPreview";
Expand Down
5 changes: 5 additions & 0 deletions src/primer-api/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,10 @@ export * from './typeDefNodeSelectionOneOfTag';
export * from './typeDefNodeSelectionOneOfThree';
export * from './typeDefNodeSelectionOneOfThreeTag';
export * from './typeDefSelection';
export * from './typeOrKind';
export * from './typeOrKindOneOf';
export * from './typeOrKindOneOfTag';
export * from './typeOrKindOneOfThree';
export * from './typeOrKindOneOfThreeTag';
export * from './uuid';
export * from './valCon';
3 changes: 3 additions & 0 deletions src/primer-api/model/nodeFlavorNoBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ export const NodeFlavorNoBody = {
TFun: 'TFun',
TApp: 'TApp',
PatternWildcard: 'PatternWildcard',
KType: 'KType',
KHole: 'KHole',
KFun: 'KFun',
} as const;
11 changes: 11 additions & 0 deletions src/primer-api/model/typeOrKind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Generated by orval v6.16.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { TypeOrKindOneOf } from './typeOrKindOneOf';
import type { TypeOrKindOneOfThree } from './typeOrKindOneOfThree';

export type TypeOrKind = TypeOrKindOneOf | TypeOrKindOneOfThree;
14 changes: 14 additions & 0 deletions src/primer-api/model/typeOrKindOneOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Generated by orval v6.16.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { Tree } from './tree';
import type { TypeOrKindOneOfTag } from './typeOrKindOneOfTag';

export type TypeOrKindOneOf = {
contents: Tree;
tag: TypeOrKindOneOfTag;
};
15 changes: 15 additions & 0 deletions src/primer-api/model/typeOrKindOneOfTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Generated by orval v6.16.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/

export type TypeOrKindOneOfTag = typeof TypeOrKindOneOfTag[keyof typeof TypeOrKindOneOfTag];


// eslint-disable-next-line @typescript-eslint/no-redeclare
export const TypeOrKindOneOfTag = {
Type: 'Type',
} as const;
Loading

0 comments on commit a824592

Please sign in to comment.