Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity type editor – Show correct properties in property selector, add edit bar, and minor changes #1184

Merged
merged 24 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
33972b9
Display list of property types in property type selector
nathggns Oct 10, 2022
dd94378
Insert the selected property when selecting it
nathggns Oct 11, 2022
692cf34
Move mapped property types out of context
nathggns Oct 11, 2022
c7cb6f8
Move mapped property types out of context
nathggns Oct 11, 2022
66c3f5f
Only display property types not yet added
nathggns Oct 11, 2022
ce2a3e7
Share expected values component
nathggns Oct 11, 2022
10b676b
Add json object type
nathggns Oct 11, 2022
da92c7a
Remove menu items which don't do anything yet
nathggns Oct 11, 2022
28f90cf
Move property type state ownership higher up
nathggns Oct 11, 2022
d7782e6
Move render of empty property list card into property list card, to s…
nathggns Oct 11, 2022
10927e5
Add edit bar
nathggns Oct 11, 2022
504a6b1
Fix font size on edit bar
nathggns Oct 11, 2022
a682454
Hide edit bar before changes are made
nathggns Oct 11, 2022
964275d
Remove unused type
nathggns Oct 11, 2022
fc6bfaa
Remove todo
nathggns Oct 11, 2022
739444a
Merge branch 'main' into nh/entity-type-view
nathggns Oct 11, 2022
509121d
Merge branch 'main' into nh/entity-type-view
nathggns Oct 11, 2022
64a9864
Lint
nathggns Oct 12, 2022
c6a316e
Merge branch 'nh/entity-type-view' of github.com:hashintel/hash into …
nathggns Oct 12, 2022
630d99a
Merge branch 'main' into nh/entity-type-view
nathggns Oct 12, 2022
05bde1e
Remove console
nathggns Oct 12, 2022
72e412f
Merge branch 'nh/entity-type-view' of github.com:hashintel/hash into …
nathggns Oct 12, 2022
a8d3d2a
Merge branch 'main' into nh/entity-type-view
nathggns Oct 12, 2022
6ea166a
Merge branch 'main' into nh/entity-type-view
nathggns Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/hash/frontend/src/lib/use-init-type-system.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import init from "@blockprotocol/type-system-web";
import { useEffect, useState } from "react";

export const useInitTypeSystem = () => {
const [loadingTypeSystem, setLoadingTypeSystem] = useState(true);

useEffect(() => {
if (loadingTypeSystem) {
void (async () => {
await init().then(() => {
setLoadingTypeSystem(false);
});
})();
}
}, [loadingTypeSystem, setLoadingTypeSystem]);

return loadingTypeSystem;
};
Original file line number Diff line number Diff line change
@@ -1,151 +1,199 @@
import { EntityType } from "@blockprotocol/type-system-web";
import { EntityType, PropertyType } from "@blockprotocol/type-system-web";
import { faAsterisk } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@hashintel/hash-design-system/fontawesome-icon";
import { Box, Container, Stack, Typography } from "@mui/material";
import { Box, Collapse, Container, Stack, Typography } from "@mui/material";
import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { useBlockProtocolGetEntityType } from "../../../../components/hooks/blockProtocolFunctions/ontology/useBlockProtocolGetEntityType";
import { FRONTEND_URL } from "../../../../lib/config";
import { useInitTypeSystem } from "../../../../lib/use-init-type-system";
import { getPlainLayout, NextPageWithLayout } from "../../../../shared/layout";
import { TopContextBar } from "../../../shared/top-context-bar";
import { EmptyPropertyListCard } from "./empty-property-list-card";
import { EditBar } from "./edit-bar";
import { HashOntologyIcon } from "./hash-ontology-icon";
import { OntologyChip } from "./ontology-chip";
import { PlaceholderIcon } from "./placeholder-icon";
import { InsertPropertyCard } from "./property-list-card";
import { useStateCallback } from "./util";
import { PropertyListCard } from "./property-list-card";
import {
PropertyTypesContext,
useRemotePropertyTypes,
} from "./use-property-types";

const useEntityType = (entityTypeSlug: string) => {
const useEntityType = (entityTypeId: string, onCompleted?: () => void) => {
const { getEntityType } = useBlockProtocolGetEntityType();
const [entityType, setEntityType] = useState<EntityType | null>(null);

const onCompletedRef = useRef(onCompleted);

useLayoutEffect(() => {
onCompletedRef.current = onCompleted;
});

useEffect(() => {
void getEntityType({
// @todo get latest version somehow?
data: { entityTypeId: `${FRONTEND_URL}${entityTypeSlug}/v/1` },
data: { entityTypeId },
}).then((value) => {
if (value.data) {
setEntityType(value.data.entityType);
onCompletedRef.current?.();
}
});
}, [getEntityType, entityTypeSlug]);
}, [getEntityType, entityTypeId]);

return entityType;
};

// @todo loading state
// @todo handle displaying entity type not yet created
const Page: NextPageWithLayout = () => {
const [mode, setMode] = useStateCallback<"empty" | "inserting">("empty");
const insertFieldRef = useRef<HTMLInputElement>(null);

const router = useRouter();
const entityType = useEntityType(router.asPath);
const [insertedPropertyTypes, setInsertedPropertyTypes] = useState<
PropertyType[]
>([]);
const [removedPropertyTypes, setRemovedPropertyTypes] = useState<
PropertyType[]
>([]);

// @todo find this out somehow
const currentVersion = 1;
const entityTypeId = `${FRONTEND_URL}/${router.query["account-slug"]}/types/entity-type/${router.query["entity-type-id"]}/v/${currentVersion}`;

if (!entityType) {
const entityType = useEntityType(entityTypeId, () => {
setInsertedPropertyTypes([]);
setRemovedPropertyTypes([]);
});

const propertyTypes = useRemotePropertyTypes();
const loadingTypeSystem = useInitTypeSystem();

if (!entityType || loadingTypeSystem) {
return null;
}

return (
<Box
component={Stack}
sx={(theme) => ({
minHeight: "100vh",
background: theme.palette.gray[10],
})}
>
<Box bgcolor="white" borderBottom={1} borderColor="gray.20">
<TopContextBar
defaultCrumbIcon={null}
crumbs={[
{
title: "Types",
href: "#",
id: "types",
},
{
title: "Entity types",
href: "#",
id: "entity-types",
},
{
title: entityType.title,
href: "#",
id: entityType.$id,
icon: <FontAwesomeIcon icon={faAsterisk} />,
},
]}
scrollToTop={() => {}}
/>
<Box pt={3.75}>
<Container>
<OntologyChip
icon={<PlaceholderIcon />}
domain="hash.ai"
path={
<>
<Typography
component="span"
fontWeight="bold"
color={(theme) => theme.palette.blue[70]}
>
{router.query["account-slug"]}
</Typography>
<Typography
component="span"
color={(theme) => theme.palette.blue[70]}
>
/types/entity-types/
</Typography>
<Typography
component="span"
fontWeight="bold"
color={(theme) => theme.palette.blue[70]}
>
{router.query["entity-type-id"]}
</Typography>
</>
}
<PropertyTypesContext.Provider value={propertyTypes}>
<Box
component={Stack}
sx={(theme) => ({
minHeight: "100vh",
background: theme.palette.gray[10],
})}
>
<Box bgcolor="white" borderBottom={1} borderColor="gray.20">
<TopContextBar
defaultCrumbIcon={null}
crumbs={[
{
title: "Types",
href: "#",
id: "types",
},
{
title: "Entity types",
href: "#",
id: "entity-types",
},
{
title: entityType.title,
href: "#",
id: entityType.$id,
icon: <FontAwesomeIcon icon={faAsterisk} />,
},
]}
scrollToTop={() => {}}
/>
<Collapse
in={insertedPropertyTypes.length + removedPropertyTypes.length > 0}
>
<EditBar
currentVersion={currentVersion}
onDiscardChanges={() => {
setInsertedPropertyTypes([]);
setRemovedPropertyTypes([]);
}}
/>
<Typography variant="h1" fontWeight="bold" mt={3} mb={4.5}>
<FontAwesomeIcon
icon={faAsterisk}
sx={(theme) => ({
fontSize: 40,
mr: 3,
color: theme.palette.gray[70],
verticalAlign: "middle",
})}
</Collapse>
<Box pt={3.75}>
<Container>
<OntologyChip
icon={<HashOntologyIcon />}
domain="hash.ai"
path={
<>
<Typography
component="span"
fontWeight="bold"
color={(theme) => theme.palette.blue[70]}
>
{router.query["account-slug"]}
</Typography>
<Typography
component="span"
color={(theme) => theme.palette.blue[70]}
>
/types/entity-types/
</Typography>
<Typography
component="span"
fontWeight="bold"
color={(theme) => theme.palette.blue[70]}
>
{router.query["entity-type-id"]}
</Typography>
</>
}
/>
{entityType.title}
</Typography>
</Container>
<Typography variant="h1" fontWeight="bold" mt={3} mb={4.5}>
<FontAwesomeIcon
icon={faAsterisk}
sx={(theme) => ({
fontSize: 40,
mr: 3,
color: theme.palette.gray[70],
verticalAlign: "middle",
})}
/>
{entityType.title}
</Typography>
</Container>
</Box>
</Box>
</Box>
<Box py={5}>
<Container>
<Typography variant="h5" mb={1.25}>
Properties of{" "}
<Box component="span" sx={{ fontWeight: "bold" }}>
{entityType.title}
</Box>
</Typography>
{mode === "empty" ? (
<EmptyPropertyListCard
onClick={() => {
setMode("inserting", () => {
insertFieldRef.current?.focus();
});
<Box py={5}>
<Container>
<Typography variant="h5" mb={1.25}>
Properties of{" "}
<Box component="span" sx={{ fontWeight: "bold" }}>
{entityType.title}
</Box>
</Typography>
<PropertyListCard
propertyTypes={insertedPropertyTypes}
onRemovePropertyType={(propertyType) => {
if (insertedPropertyTypes.includes(propertyType)) {
const nextInsertedPropertyTypes =
insertedPropertyTypes.filter(
(type) => type !== propertyType,
);
setInsertedPropertyTypes(nextInsertedPropertyTypes);
} else if (!removedPropertyTypes.includes(propertyType)) {
setRemovedPropertyTypes([
...removedPropertyTypes,
propertyType,
]);
}
}}
/>
) : (
<InsertPropertyCard
insertFieldRef={insertFieldRef}
onCancel={() => {
setMode("empty");
onAddPropertyType={(propertyType) => {
if (!insertedPropertyTypes.includes(propertyType)) {
setInsertedPropertyTypes([
...insertedPropertyTypes,
propertyType,
]);
}
}}
/>
)}
</Container>
</Container>
</Box>
</Box>
</Box>
</PropertyTypesContext.Provider>
);
};

Expand Down
Loading