From bd1f030ee3c987090011b5dec2993ebe50d5944b Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 11 Apr 2024 16:51:53 -0700 Subject: [PATCH 01/16] First attempt at renaming --- .../migration.sql | 10 +++ .../20240411205304_gs/migration.sql | 30 +++++++++ packages/hub/prisma/schema.prisma | 4 +- packages/hub/schema.graphql | 64 +++++++++---------- packages/hub/src/__generated__/.gitkeep | 0 packages/hub/src/app/FrontPage.tsx | 6 +- .../hub/src/app/FrontPageModelExportList.tsx | 43 ------------- .../hub/src/app/FrontPageVariableList.tsx | 40 ++++++++++++ .../[slug]/EditSquiggleSnippetModel.tsx | 16 ++--- .../[owner]/[slug]/ModelEntityNodes.tsx | 4 +- .../app/models/[owner]/[slug]/ModelLayout.tsx | 43 ++++++------- .../RelativeValuesModelLayout.tsx | 2 +- .../[slug]/revisions/ModelRevisionsList.tsx | 8 +-- .../src/app/users/[username]/UserLayout.tsx | 8 +-- .../exports/UserModelExportList.tsx | 45 ------------- .../src/app/users/[username]/exports/page.tsx | 25 -------- .../[username]/variables/UserVariableList.tsx | 45 +++++++++++++ .../UserVariablePage.tsx} | 14 ++-- .../app/users/[username]/variables/page.tsx | 25 ++++++++ ...EditModelExports.tsx => EditVariables.tsx} | 10 +-- .../queries/{exports.ts => variables.ts} | 14 ++-- packages/hub/src/graphql/schema.ts | 2 +- packages/hub/src/graphql/types/Group.ts | 10 +-- packages/hub/src/graphql/types/Model.ts | 4 +- .../hub/src/graphql/types/ModelRevision.ts | 2 +- packages/hub/src/graphql/types/User.ts | 15 ++--- .../types/{ModelExport.ts => Variable.ts} | 13 ++-- ...ortsDropdown.tsx => VariablesDropdown.tsx} | 33 +++++----- .../hub/src/models/components/ModelCard.tsx | 18 +++--- packages/hub/src/routes.ts | 6 +- .../buildRecentModelRevision/worker.ts | 2 +- .../components/VariableCard.tsx} | 38 +++++------ .../components/VariableList.tsx} | 14 ++-- packages/hub/test/gql-gen/graphql.ts | 12 ++-- 34 files changed, 328 insertions(+), 297 deletions(-) create mode 100644 packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql create mode 100644 packages/hub/prisma/migrations/20240411205304_gs/migration.sql delete mode 100644 packages/hub/src/__generated__/.gitkeep delete mode 100644 packages/hub/src/app/FrontPageModelExportList.tsx create mode 100644 packages/hub/src/app/FrontPageVariableList.tsx delete mode 100644 packages/hub/src/app/users/[username]/exports/UserModelExportList.tsx delete mode 100644 packages/hub/src/app/users/[username]/exports/page.tsx create mode 100644 packages/hub/src/app/users/[username]/variables/UserVariableList.tsx rename packages/hub/src/app/users/[username]/{exports/UserModelExportsPage.tsx => variables/UserVariablePage.tsx} (58%) create mode 100644 packages/hub/src/app/users/[username]/variables/page.tsx rename packages/hub/src/components/exports/{EditModelExports.tsx => EditVariables.tsx} (94%) rename packages/hub/src/graphql/queries/{exports.ts => variables.ts} (77%) rename packages/hub/src/graphql/types/{ModelExport.ts => Variable.ts} (80%) rename packages/hub/src/lib/{ExportsDropdown.tsx => VariablesDropdown.tsx} (76%) rename packages/hub/src/{modelExports/components/ModelExportCard.tsx => variables/components/VariableCard.tsx} (60%) rename packages/hub/src/{modelExports/components/ModelExportList.tsx => variables/components/VariableList.tsx} (60%) diff --git a/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql b/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql new file mode 100644 index 0000000000..f5d9bf03ce --- /dev/null +++ b/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql @@ -0,0 +1,10 @@ +ALTER TABLE "ModelExport" DROP CONSTRAINT "ModelExport_modelRevisionId_fkey"; + +-- RenameTable +ALTER TABLE "ModelExport" RENAME TO "VariableExportRevision"; + +-- RenameIndex +ALTER INDEX "ModelExport_modelRevisionId_variableName_key" RENAME TO "VariableExportRevision_modelRevisionId_variableName_key"; + +-- AddForeignKey +ALTER TABLE "VariableExportRevision" ADD CONSTRAINT "VariableExportRevision_modelRevisionId_fkey" FOREIGN KEY ("modelRevisionId") REFERENCES "ModelRevision"("id") ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file diff --git a/packages/hub/prisma/migrations/20240411205304_gs/migration.sql b/packages/hub/prisma/migrations/20240411205304_gs/migration.sql new file mode 100644 index 0000000000..310b9c9a45 --- /dev/null +++ b/packages/hub/prisma/migrations/20240411205304_gs/migration.sql @@ -0,0 +1,30 @@ +/* + Warnings: + + - You are about to drop the `VariableExportRevision` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "VariableExportRevision" DROP CONSTRAINT "VariableExportRevision_modelRevisionId_fkey"; + +-- DropTable +DROP TABLE "VariableExportRevision"; + +-- CreateTable +CREATE TABLE "Variable" ( + "id" TEXT NOT NULL, + "modelRevisionId" TEXT NOT NULL, + "variableName" TEXT NOT NULL, + "title" TEXT, + "docstring" TEXT NOT NULL DEFAULT '', + "variableType" TEXT NOT NULL DEFAULT 'OTHER', + "isCurrent" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Variable_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Variable_modelRevisionId_variableName_key" ON "Variable"("modelRevisionId", "variableName"); + +-- AddForeignKey +ALTER TABLE "Variable" ADD CONSTRAINT "Variable_modelRevisionId_fkey" FOREIGN KEY ("modelRevisionId") REFERENCES "ModelRevision"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/hub/prisma/schema.prisma b/packages/hub/prisma/schema.prisma index 13bbeb8812..2c7010f8d0 100644 --- a/packages/hub/prisma/schema.prisma +++ b/packages/hub/prisma/schema.prisma @@ -219,7 +219,7 @@ model ModelRevision { contentId String? @unique relativeValuesExports RelativeValuesExport[] - exports ModelExport[] + variables Variable[] // required by Prisma, but unused since `model` field should point at the same entity currentRevisionModel Model? @relation("CurrentRevision") @@ -252,7 +252,7 @@ model SquiggleSnippet { revision ModelRevision? } -model ModelExport { +model Variable { id String @id @default(cuid()) modelRevision ModelRevision @relation(fields: [modelRevisionId], references: [id], onDelete: Cascade) modelRevisionId String diff --git a/packages/hub/schema.graphql b/packages/hub/schema.graphql index f75ff7249b..2dc4edabeb 100644 --- a/packages/hub/schema.graphql +++ b/packages/hub/schema.graphql @@ -90,7 +90,7 @@ type Group implements Node & Owner { inviteForMe: GroupInvite invites(after: String, before: String, first: Int, last: Int): GroupInviteConnection memberships(after: String, before: String, first: Int, last: Int): UserGroupMembershipConnection! - modelExports(after: String, before: String, first: Int, last: Int): ModelExport! + modelExports(after: String, before: String, first: Int, last: Int): Variable! models(after: String, before: String, first: Int, last: Int): ModelConnection! myMembership: UserGroupMembership reusableInviteToken: String @@ -177,33 +177,6 @@ type ModelEdge { node: Model! } -type ModelExport implements Node { - docstring: String! - id: ID! - isCurrent: Boolean! - modelRevision: ModelRevision! - owner: Owner! - title: String - variableName: String! - variableType: String! -} - -type ModelExportConnection { - edges: [ModelExportEdge!]! - pageInfo: PageInfo! -} - -type ModelExportEdge { - cursor: String! - node: ModelExport! -} - -input ModelExportQueryInput { - modelId: String - owner: String - variableName: String -} - type ModelExportRevisionsConnection { edges: [ModelExportRevisionsConnectionEdge!]! pageInfo: PageInfo! @@ -211,7 +184,7 @@ type ModelExportRevisionsConnection { type ModelExportRevisionsConnectionEdge { cursor: String! - node: ModelExport! + node: Variable! } type ModelRevision implements Node { @@ -221,12 +194,12 @@ type ModelRevision implements Node { content: ModelContent! createdAtTimestamp: Float! exportNames: [String!]! - exports: [ModelExport!]! forRelativeValues(input: ModelRevisionForRelativeValuesInput!): ModelRevisionForRelativeValuesResult! id: ID! lastBuild: ModelRevisionBuild model: Model! relativeValuesExports: [RelativeValuesExport!]! + variables: [Variable!]! } type ModelRevisionBuild implements Node { @@ -542,7 +515,6 @@ type Query { groups(after: String, before: String, first: Int, input: GroupsQueryInput, last: Int): GroupConnection! me: Me! model(input: QueryModelInput!): QueryModelResult! - modelExports(after: String, before: String, first: Int, input: ModelExportQueryInput, last: Int): ModelExportConnection! models(after: String, before: String, first: Int, last: Int): ModelConnection! """Admin-only query for listing models in /admin UI""" @@ -555,6 +527,7 @@ type Query { search(after: String, before: String, first: Int, last: Int, text: String!): QuerySearchResult! userByUsername(username: String!): QueryUserByUsernameResult! users(after: String, before: String, first: Int, input: UsersQueryInput, last: Int): QueryUsersConnection! + variables(after: String, before: String, first: Int, input: VariableQueryInput, last: Int): VariableConnection! } union QueryGroupResult = BaseError | Group | NotFoundError @@ -756,11 +729,11 @@ type User implements Node & Owner { groups(after: String, before: String, first: Int, last: Int): GroupConnection! id: ID! isRoot: Boolean! - modelExports(after: String, before: String, first: Int, last: Int): ModelExportConnection! models(after: String, before: String, first: Int, last: Int): ModelConnection! relativeValuesDefinitions(after: String, before: String, first: Int, last: Int): RelativeValuesDefinitionConnection! slug: String! username: String! + variables(after: String, before: String, first: Int, last: Int): VariableConnection! } type UserGroupInvite implements GroupInvite & Node { @@ -803,4 +776,31 @@ type ValidationError implements Error { type ValidationErrorIssue { message: String! path: [String!]! +} + +type Variable implements Node { + docstring: String! + id: ID! + isCurrent: Boolean! + modelRevision: ModelRevision! + owner: Owner! + title: String + variableName: String! + variableType: String! +} + +type VariableConnection { + edges: [VariableEdge!]! + pageInfo: PageInfo! +} + +type VariableEdge { + cursor: String! + node: Variable! +} + +input VariableQueryInput { + modelId: String + owner: String + variableName: String } \ No newline at end of file diff --git a/packages/hub/src/__generated__/.gitkeep b/packages/hub/src/__generated__/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/hub/src/app/FrontPage.tsx b/packages/hub/src/app/FrontPage.tsx index cae4a2fdc8..cc02ef6ddc 100644 --- a/packages/hub/src/app/FrontPage.tsx +++ b/packages/hub/src/app/FrontPage.tsx @@ -9,15 +9,15 @@ import { usePageQuery } from "@/relay/usePageQuery"; import { FrontPageDefinitionList } from "./FrontPageDefinitionList"; import { FrontPageGroupList } from "./FrontPageGroupList"; -import { FrontPageModelExportList } from "./FrontPageModelExportList"; import { FrontPageModelList } from "./FrontPageModelList"; +import { FrontPageVariableList } from "./FrontPageVariableList"; import { FrontPageQuery } from "@/__generated__/FrontPageQuery.graphql"; const Query = graphql` query FrontPageQuery { ...FrontPageModelList - ...FrontPageModelExportList + ...FrontPageVariableList ...FrontPageDefinitionList ...FrontPageGroupList } @@ -43,7 +43,7 @@ export const FrontPage: FC<{ - + diff --git a/packages/hub/src/app/FrontPageModelExportList.tsx b/packages/hub/src/app/FrontPageModelExportList.tsx deleted file mode 100644 index 1a02285e70..0000000000 --- a/packages/hub/src/app/FrontPageModelExportList.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import { FC } from "react"; -import { graphql, usePaginationFragment } from "react-relay"; - -import { ModelExportList } from "@/modelExports/components/ModelExportList"; - -import { FrontPageModelExportList$key } from "@/__generated__/FrontPageModelExportList.graphql"; -import { FrontPageModelExportListPaginationQuery } from "@/__generated__/FrontPageModelExportListPaginationQuery.graphql"; - -const Fragment = graphql` - fragment FrontPageModelExportList on Query - @argumentDefinitions( - cursor: { type: "String" } - count: { type: "Int", defaultValue: 20 } - ) - @refetchable(queryName: "FrontPageModelExportListPaginationQuery") { - modelExports(first: $count, after: $cursor) - @connection(key: "FrontPageModelExportList_modelExports") { - # necessary for Relay - edges { - __typename - } - ...ModelExportList - } - } -`; - -type Props = { - dataRef: FrontPageModelExportList$key; -}; - -export const FrontPageModelExportList: FC = ({ dataRef }) => { - const { - data: { modelExports }, - loadNext, - } = usePaginationFragment< - FrontPageModelExportListPaginationQuery, - FrontPageModelExportList$key - >(Fragment, dataRef); - - return ; -}; diff --git a/packages/hub/src/app/FrontPageVariableList.tsx b/packages/hub/src/app/FrontPageVariableList.tsx new file mode 100644 index 0000000000..1859369ae9 --- /dev/null +++ b/packages/hub/src/app/FrontPageVariableList.tsx @@ -0,0 +1,40 @@ +"use client"; + +import { FC } from "react"; +import { graphql, usePaginationFragment } from "react-relay"; + +import { VariableList } from "@/variables/components/VariableList"; + +const Fragment = graphql` + fragment FrontPageVariableList on Query + @argumentDefinitions( + cursor: { type: "String" } + count: { type: "Int", defaultValue: 20 } + ) + @refetchable(queryName: "FrontPageVariableListPaginationQuery") { + variables(first: $count, after: $cursor) + @connection(key: "FrontPageVariableList_variables") { + # necessary for Relay + edges { + __typename + } + ...VariableList + } + } +`; + +type Props = { + dataRef: FrontPageVariableList$key; +}; + +export const FrontPageVariableList: FC = ({ dataRef }) => { + const { + data: { variables }, + loadNext, + } = usePaginationFragment< + FrontPageVariableListPaginationQuery, + FrontPageVariableList$key + >(Fragment, dataRef); + + return ; +}; diff --git a/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx b/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx index b6340bf481..5c27a9e63b 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx @@ -28,14 +28,14 @@ import { versionSupportsOnOpenExport, } from "@quri/versioned-squiggle-components"; -import { EditModelExports } from "@/components/exports/EditModelExports"; +import { EditVariables } from "@/components/exports/EditVariables"; import { ReactRoot } from "@/components/ReactRoot"; import { FormModal } from "@/components/ui/FormModal"; import { SAMPLE_COUNT_DEFAULT, XY_POINT_LENGTH_DEFAULT } from "@/constants"; import { useAvailableHeight } from "@/hooks/useAvailableHeight"; import { useMutationForm } from "@/hooks/useMutationForm"; import { extractFromGraphqlErrorUnion } from "@/lib/graphqlHelpers"; -import { modelExportRoute, modelRoute } from "@/routes"; +import { modelRoute, variableRoute } from "@/routes"; import { ImportTooltip } from "@/squiggle/components/ImportTooltip"; import { parseSourceId, @@ -137,7 +137,7 @@ export const EditSquiggleSnippetModel: FC = ({ id slug isEditable - ...EditModelExports_Model + ...EditVariables_Model ...SquiggleSnippetDraftDialog_Model owner { slug @@ -162,7 +162,7 @@ export const EditSquiggleSnippetModel: FC = ({ } } exportNames - exports { + variables { id variableName variableType @@ -357,11 +357,11 @@ export const EditSquiggleSnippetModel: FC = ({ ), renderExtraModal: (name) => { - if (name === "exports") { + if (name === "variables") { return { body: (
- { appendVariableWithDefinition(item); onSubmit(); @@ -398,7 +398,7 @@ export const EditSquiggleSnippetModel: FC = ({ openModal("exports")} + onClick={() => openModal("variables")} /> ) : null; @@ -428,7 +428,7 @@ export const EditSquiggleSnippetModel: FC = ({ const { owner, slug } = parseSourceId(sourceId); if (varName) { router.push( - modelExportRoute({ owner, modelSlug: slug, variableName: varName }) + variableRoute({ owner, modelSlug: slug, variableName: varName }) ); } else { router.push(modelRoute({ owner, slug })); diff --git a/packages/hub/src/app/models/[owner]/[slug]/ModelEntityNodes.tsx b/packages/hub/src/app/models/[owner]/[slug]/ModelEntityNodes.tsx index 83d1415b44..378f23964f 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/ModelEntityNodes.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/ModelEntityNodes.tsx @@ -10,10 +10,10 @@ import { type EntityNode } from "@/components/EntityLayout"; import { ownerIcon } from "@/lib/ownerIcon"; import { isModelRelativeValuesRoute, - modelExportRoute, modelForRelativeValuesExportRoute, modelRoute, ownerRoute, + variableRoute, } from "@/routes"; function hasTypename(owner: { @@ -67,7 +67,7 @@ function entityNodes( if (variable && variable.type === "EXPORT") { nodes.push({ slug: variable.name, - href: modelExportRoute({ + href: variableRoute({ owner: owner.slug, modelSlug: slug, variableName: variable.name, diff --git a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx index a3b87f73c7..a98f1ca3e6 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx @@ -7,12 +7,12 @@ import { CodeBracketIcon, RectangleStackIcon, ShareIcon } from "@quri/ui"; import { EntityLayout } from "@/components/EntityLayout"; import { EntityTab } from "@/components/ui/EntityTab"; +import { extractFromGraphqlErrorUnion } from "@/lib/graphqlHelpers"; import { - ExportsDropdown, - type ModelExport, totalImportLength, -} from "@/lib/ExportsDropdown"; -import { extractFromGraphqlErrorUnion } from "@/lib/graphqlHelpers"; + type Variable, + VariablesDropdown, +} from "@/lib/VariablesDropdown"; import { SerializablePreloadedQuery } from "@/relay/loadPageQuery"; import { usePageQuery } from "@/relay/usePageQuery"; import { modelRevisionsRoute, modelRoute } from "@/routes"; @@ -50,7 +50,7 @@ const Query = graphql` id # for length; TODO - "hasExports" field? exportNames - exports { + variables { id variableName variableType @@ -86,19 +86,17 @@ export const ModelLayout: FC< slug: model.slug, }); - const modelExports: ModelExport[] = model.currentRevision.exportNames.map( - (name) => { - const matchingExport = model.currentRevision.exports.find( - (e) => e.variableName === name - ); + const variable: Variable[] = model.currentRevision.exportNames.map((name) => { + const matchingExport = model.currentRevision.exports.find( + (e) => e.variableName === name + ); - return { - variableName: name, - variableType: matchingExport?.variableType || undefined, - title: matchingExport?.title || undefined, - }; - } - ); + return { + variableName: name, + variableType: matchingExport?.variableType || undefined, + title: matchingExport?.title || undefined, + }; + }); const relativeValuesExports = model.currentRevision.relativeValuesExports.map( ({ variableName, definition: { slug } }) => ({ @@ -107,10 +105,7 @@ export const ModelLayout: FC< }) ); - const _totalImportLength = totalImportLength( - modelExports, - relativeValuesExports - ); + const _totalImportLength = totalImportLength(variable, relativeValuesExports); return ( {Boolean(_totalImportLength) && ( - - + )} {`Build Time: ${revision.lastBuild.runSeconds.toFixed(2)}s`}
)} - {revision.exports.length > 0 ? ( + {revision.variables.length > 0 ? (
- {`${revision.exports.length} exports `} + {`${revision.variables.length} exports `}
) : null} @@ -135,7 +135,7 @@ export const ModelRevisionsList: FC<{ id createdAtTimestamp buildStatus - exports { + variables { id title variableName diff --git a/packages/hub/src/app/users/[username]/UserLayout.tsx b/packages/hub/src/app/users/[username]/UserLayout.tsx index 9f3e0e0664..a22117b427 100644 --- a/packages/hub/src/app/users/[username]/UserLayout.tsx +++ b/packages/hub/src/app/users/[username]/UserLayout.tsx @@ -17,8 +17,8 @@ import { newModelRoute, userDefinitionsRoute, userGroupsRoute, - userModelExportsRoute, userRoute, + userVariablesRoute, } from "@/routes"; import { UserLayoutQuery } from "@/__generated__/UserLayoutQuery.graphql"; @@ -42,7 +42,7 @@ const Query = graphql` __typename } } - modelExports(first: 1) { + variables(first: 1) { edges { __typename } @@ -116,10 +116,10 @@ export const UserLayout: FC< href={userRoute({ username: user.username })} /> ) : null} - {isMe || user.modelExports.edges.length ? ( + {isMe || user.variables.edges.length ? ( ) : null} {isMe || user.relativeValuesDefinitions.edges.length ? ( diff --git a/packages/hub/src/app/users/[username]/exports/UserModelExportList.tsx b/packages/hub/src/app/users/[username]/exports/UserModelExportList.tsx deleted file mode 100644 index 641c52142e..0000000000 --- a/packages/hub/src/app/users/[username]/exports/UserModelExportList.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { FC } from "react"; -import { usePaginationFragment } from "react-relay"; -import { graphql } from "relay-runtime"; - -import { ModelExportList } from "@/modelExports/components/ModelExportList"; - -import { UserModelExportList$key } from "@/__generated__/UserModelExportList.graphql"; - -const Fragment = graphql` - fragment UserModelExportList on User - @argumentDefinitions( - cursor: { type: "String" } - count: { type: "Int", defaultValue: 20 } - ) - @refetchable(queryName: "UserModelExportListPaginationQuery") { - modelExports(first: $count, after: $cursor) - @connection(key: "UserModelExportList_modelExports") { - edges { - __typename - } - ...ModelExportList - } - } -`; - -type Props = { - dataRef: UserModelExportList$key; -}; - -export const UserModelExportList: FC = ({ dataRef }) => { - const { - data: { modelExports }, - loadNext, - } = usePaginationFragment(Fragment, dataRef); - - return ( -
- {modelExports.edges.length ? ( - - ) : ( -
No modelExport to show.
- )} -
- ); -}; diff --git a/packages/hub/src/app/users/[username]/exports/page.tsx b/packages/hub/src/app/users/[username]/exports/page.tsx deleted file mode 100644 index b79bed155e..0000000000 --- a/packages/hub/src/app/users/[username]/exports/page.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Metadata } from "next"; - -import { loadPageQuery } from "@/relay/loadPageQuery"; - -import { UserModelExportsPage } from "./UserModelExportsPage"; - -import QueryNode, { - UserModelExportsPageQuery, -} from "@/__generated__/UserModelExportsPageQuery.graphql"; - -type Props = { - params: { username: string }; -}; - -export default async function OuterUserModelExportsPage({ params }: Props) { - const query = await loadPageQuery(QueryNode, { - username: params.username, - }); - - return ; -} - -export function generateMetadata({ params }: Props): Metadata { - return { title: params.username }; -} diff --git a/packages/hub/src/app/users/[username]/variables/UserVariableList.tsx b/packages/hub/src/app/users/[username]/variables/UserVariableList.tsx new file mode 100644 index 0000000000..07f622ae1f --- /dev/null +++ b/packages/hub/src/app/users/[username]/variables/UserVariableList.tsx @@ -0,0 +1,45 @@ +import { FC } from "react"; +import { usePaginationFragment } from "react-relay"; +import { graphql } from "relay-runtime"; + +import { VariableList } from "@/variables/components/VariableList"; + +import { UserVariableList$key } from "@/__generated__/UserVariableList.graphql"; + +const Fragment = graphql` + fragment UserVariableList on User + @argumentDefinitions( + cursor: { type: "String" } + count: { type: "Int", defaultValue: 20 } + ) + @refetchable(queryName: "UserVariableListPaginationQuery") { + variables(first: $count, after: $cursor) + @connection(key: "UserVariableList_variables") { + edges { + __typename + } + ...VariableList + } + } +`; + +type Props = { + dataRef: UserVariableList$key; +}; + +export const UserVariableList: FC = ({ dataRef }) => { + const { + data: { variables }, + loadNext, + } = usePaginationFragment(Fragment, dataRef); + + return ( +
+ {variables.edges.length ? ( + + ) : ( +
No modelExport to show.
+ )} +
+ ); +}; diff --git a/packages/hub/src/app/users/[username]/exports/UserModelExportsPage.tsx b/packages/hub/src/app/users/[username]/variables/UserVariablePage.tsx similarity index 58% rename from packages/hub/src/app/users/[username]/exports/UserModelExportsPage.tsx rename to packages/hub/src/app/users/[username]/variables/UserVariablePage.tsx index 90ab30d24b..4da0a10a63 100644 --- a/packages/hub/src/app/users/[username]/exports/UserModelExportsPage.tsx +++ b/packages/hub/src/app/users/[username]/variables/UserVariablePage.tsx @@ -6,27 +6,27 @@ import { extractFromGraphqlErrorUnion } from "@/lib/graphqlHelpers"; import { SerializablePreloadedQuery } from "@/relay/loadPageQuery"; import { usePageQuery } from "@/relay/usePageQuery"; -import { UserModelExportList } from "./UserModelExportList"; +import { UserVariableList } from "./UserVariableList"; -import { UserModelExportsPageQuery } from "@/__generated__/UserModelExportsPageQuery.graphql"; +import { UserVariablePageQuery } from "@/__generated__/UserVariablesPageQuery.graphql"; const Query = graphql` - query UserModelExportsPageQuery($username: String!) { + query UserVariablePageQuery($username: String!) { userByUsername(username: $username) { __typename ... on User { - ...UserModelExportList + ...UserVariableList } } } `; -export const UserModelExportsPage: FC<{ - query: SerializablePreloadedQuery; +export const UserVariablesPage: FC<{ + query: SerializablePreloadedQuery; }> = ({ query }) => { const [{ userByUsername: result }] = usePageQuery(Query, query); const user = extractFromGraphqlErrorUnion(result, "User"); - return ; + return ; }; diff --git a/packages/hub/src/app/users/[username]/variables/page.tsx b/packages/hub/src/app/users/[username]/variables/page.tsx new file mode 100644 index 0000000000..19008f815a --- /dev/null +++ b/packages/hub/src/app/users/[username]/variables/page.tsx @@ -0,0 +1,25 @@ +import { Metadata } from "next"; + +import { loadPageQuery } from "@/relay/loadPageQuery"; + +import { UserVariablesPage } from "./UserVariablePage"; + +import QueryNode, { + UserVariablesPageQuery, +} from "@/__generated__/UserVariablesPageQuery.graphql"; + +type Props = { + params: { username: string }; +}; + +export default async function OuterUserVariablesPage({ params }: Props) { + const query = await loadPageQuery(QueryNode, { + username: params.username, + }); + + return ; +} + +export function generateMetadata({ params }: Props): Metadata { + return { title: params.username }; +} diff --git a/packages/hub/src/components/exports/EditModelExports.tsx b/packages/hub/src/components/exports/EditVariables.tsx similarity index 94% rename from packages/hub/src/components/exports/EditModelExports.tsx rename to packages/hub/src/components/exports/EditVariables.tsx index ba948c9e30..acd400202c 100644 --- a/packages/hub/src/components/exports/EditModelExports.tsx +++ b/packages/hub/src/components/exports/EditVariables.tsx @@ -20,8 +20,8 @@ import { SelectRelativeValuesDefinitionOption, } from "./SelectRelativeValuesDefinition"; -import { EditModelExports_Model$key } from "@/__generated__/EditModelExports_Model.graphql"; import { RelativeValuesExportInput } from "@/__generated__/EditSquiggleSnippetModelMutation.graphql"; +import { EditVariables_Model$key } from "@/__generated__/EditVariables_Model.graphql"; const CreateVariableWithDefinitionModal: FC<{ close: () => void; @@ -90,12 +90,12 @@ const CreateVariableWithDefinitionModal: FC<{ const ExportItem: FC<{ item: RelativeValuesExportInput; - modelRef: EditModelExports_Model$key; + modelRef: EditVariables_Model$key; remove: () => void; }> = ({ item, modelRef, remove }) => { const model = useFragment( graphql` - fragment EditModelExports_Model on Model { + fragment EditVariables_Model on Model { id slug owner { @@ -139,10 +139,10 @@ type Props = { append: (item: RelativeValuesExportInput) => void; remove: (id: number) => void; items: RelativeValuesExportInput[]; - modelRef: EditModelExports_Model$key; + modelRef: EditVariables_Model$key; }; -export const EditModelExports: FC = ({ +export const EditVariables: FC = ({ append, remove, items, diff --git a/packages/hub/src/graphql/queries/exports.ts b/packages/hub/src/graphql/queries/variables.ts similarity index 77% rename from packages/hub/src/graphql/queries/exports.ts rename to packages/hub/src/graphql/queries/variables.ts index e74f0940ac..47d3685f5c 100644 --- a/packages/hub/src/graphql/queries/exports.ts +++ b/packages/hub/src/graphql/queries/variables.ts @@ -4,9 +4,9 @@ import { builder } from "@/graphql/builder"; import { prisma } from "@/prisma"; import { modelWhereHasAccess } from "../helpers/modelHelpers"; -import { ModelExport, ModelExportConnection } from "../types/ModelExport"; +import { Variable, VariableConnection } from "../types/Variable"; -const ModelExportQueryInput = builder.inputType("ModelExportQueryInput", { +const VariableQueryInput = builder.inputType("VariableQueryInput", { fields: (t) => ({ modelId: t.string(), variableName: t.string(), @@ -14,13 +14,13 @@ const ModelExportQueryInput = builder.inputType("ModelExportQueryInput", { }), }); -builder.queryField("modelExports", (t) => +builder.queryField("variables", (t) => t.prismaConnection( { - type: ModelExport, + type: Variable, cursor: "id", args: { - input: t.arg({ type: ModelExportQueryInput }), + input: t.arg({ type: VariableQueryInput }), }, resolve: (query, _, { input }, { session }) => { const modelId = input?.modelId; @@ -42,7 +42,7 @@ builder.queryField("modelExports", (t) => } ); - return prisma.modelExport.findMany({ + return prisma.variable.findMany({ ...query, where: { ...queries, @@ -56,6 +56,6 @@ builder.queryField("modelExports", (t) => }); }, }, - ModelExportConnection + VariableConnection ) ); diff --git a/packages/hub/src/graphql/schema.ts b/packages/hub/src/graphql/schema.ts index 2ddfe7f5cb..48a4fa44a8 100644 --- a/packages/hub/src/graphql/schema.ts +++ b/packages/hub/src/graphql/schema.ts @@ -6,7 +6,7 @@ import "./queries/group"; import "./queries/groups"; import "./queries/me"; import "./queries/model"; -import "./queries/exports"; +import "./queries/variables"; import "./queries/models"; import "./queries/modelsByVersion"; import "./queries/relativeValuesDefinition"; diff --git a/packages/hub/src/graphql/types/Group.ts b/packages/hub/src/graphql/types/Group.ts index c287e6f4cb..76cc177463 100644 --- a/packages/hub/src/graphql/types/Group.ts +++ b/packages/hub/src/graphql/types/Group.ts @@ -6,8 +6,8 @@ import { getMyMembershipById } from "../helpers/groupHelpers"; import { modelWhereHasAccess } from "../helpers/modelHelpers"; import { GroupInvite, GroupInviteConnection } from "./GroupInvite"; import { ModelConnection, modelConnectionHelpers } from "./Model"; -import { modelExportConnectionHelpers } from "./ModelExport"; import { Owner } from "./Owner"; +import { variableConnectionHelpers } from "./Variable"; export const MembershipRoleType = builder.enumType(MembershipRole, { name: "MembershipRole", @@ -133,7 +133,7 @@ export const Group = builder.prismaNode("Group", { ), modelExports: t.connection( { - type: modelExportConnectionHelpers.ref, + type: variableConnectionHelpers.ref, select: (args, ctx, nestedSelection) => ({ asOwner: { select: { @@ -142,7 +142,7 @@ export const Group = builder.prismaNode("Group", { currentRevision: { select: { exports: { - ...modelExportConnectionHelpers.getQuery( + ...variableConnectionHelpers.getQuery( args, ctx, nestedSelection @@ -160,10 +160,10 @@ export const Group = builder.prismaNode("Group", { group.asOwner?.models .map((model) => model.currentRevision?.exports ?? []) .flat() ?? []; - return modelExportConnectionHelpers.resolve(exports, args, ctx); + return variableConnectionHelpers.resolve(exports, args, ctx); }, }, - modelExportConnectionHelpers.ref + variableConnectionHelpers.ref ), }), }); diff --git a/packages/hub/src/graphql/types/Model.ts b/packages/hub/src/graphql/types/Model.ts index 4e506074ab..e10a38f7a8 100644 --- a/packages/hub/src/graphql/types/Model.ts +++ b/packages/hub/src/graphql/types/Model.ts @@ -3,9 +3,9 @@ import { prismaConnectionHelpers } from "@pothos/plugin-prisma"; import { builder } from "@/graphql/builder"; import { decodeGlobalIdWithTypename } from "../utils"; -import { ModelExport } from "./ModelExport"; import { ModelRevision, ModelRevisionConnection } from "./ModelRevision"; import { Owner } from "./Owner"; +import { Variable } from "./Variable"; export const Model = builder.prismaNode("Model", { id: { field: "id" }, @@ -100,7 +100,7 @@ export const Model = builder.prismaNode("Model", { ModelRevisionConnection ), exportRevisions: t.connection({ - type: ModelExport, + type: Variable, args: exportRevisionConnectionHelpers.getArgs(), select: (args, ctx, nestedSelection) => ({ revisions: exportRevisionConnectionHelpers.getQuery( diff --git a/packages/hub/src/graphql/types/ModelRevision.ts b/packages/hub/src/graphql/types/ModelRevision.ts index aacbcb4123..99bc6d41fb 100644 --- a/packages/hub/src/graphql/types/ModelRevision.ts +++ b/packages/hub/src/graphql/types/ModelRevision.ts @@ -58,7 +58,7 @@ export const ModelRevision = builder.prismaNode("ModelRevision", { // `relatedConnection` would be more principled, and in theory the number of variables with definitions could be high. // But connection is harder to deal with on the UI side, and since we send all variables back on updates, so it doesn't make much sense there. relativeValuesExports: t.relation("relativeValuesExports"), - exports: t.relation("exports"), + variables: t.relation("variables"), model: t.relation("model"), lastBuild: t.field({ diff --git a/packages/hub/src/graphql/types/User.ts b/packages/hub/src/graphql/types/User.ts index 0c3e5c90b0..edeee0621f 100644 --- a/packages/hub/src/graphql/types/User.ts +++ b/packages/hub/src/graphql/types/User.ts @@ -3,15 +3,12 @@ import { modelWhereHasAccess } from "../helpers/modelHelpers"; import { isRootUser } from "../helpers/userHelpers"; import { GroupConnection, groupFromMembershipConnectionHelpers } from "./Group"; import { ModelConnection, modelConnectionHelpers } from "./Model"; -import { - ModelExportConnection, - modelExportConnectionHelpers, -} from "./ModelExport"; import { Owner } from "./Owner"; import { RelativeValuesDefinitionConnection, relativeValuesDefinitionConnectionHelpers, } from "./RelativeValuesDefinition"; +import { VariableConnection, variableConnectionHelpers } from "./Variable"; export const User = builder.prismaNode("User", { id: { field: "id" }, @@ -57,9 +54,9 @@ export const User = builder.prismaNode("User", { }, ModelConnection ), - modelExports: t.connection( + variables: t.connection( { - type: modelExportConnectionHelpers.ref, + type: variableConnectionHelpers.ref, select: (args, ctx, nestedSelection) => ({ asOwner: { select: { @@ -67,7 +64,7 @@ export const User = builder.prismaNode("User", { select: { currentRevision: { select: { - exports: modelExportConnectionHelpers.getQuery( + exports: variableConnectionHelpers.getQuery( args, ctx, nestedSelection @@ -84,10 +81,10 @@ export const User = builder.prismaNode("User", { user.asOwner?.models .map((model) => model.currentRevision?.exports ?? []) .flat() ?? []; - return modelExportConnectionHelpers.resolve(exports, args, ctx); + return variableConnectionHelpers.resolve(exports, args, ctx); }, }, - ModelExportConnection + VariableConnection ), relativeValuesDefinitions: t.connection( { diff --git a/packages/hub/src/graphql/types/ModelExport.ts b/packages/hub/src/graphql/types/Variable.ts similarity index 80% rename from packages/hub/src/graphql/types/ModelExport.ts rename to packages/hub/src/graphql/types/Variable.ts index 3354c19582..89b82cd412 100644 --- a/packages/hub/src/graphql/types/ModelExport.ts +++ b/packages/hub/src/graphql/types/Variable.ts @@ -1,11 +1,10 @@ import { prismaConnectionHelpers } from "@pothos/plugin-prisma"; import { builder } from "@/graphql/builder"; -import { prisma } from "@/prisma"; import { Owner } from "./Owner"; -export const ModelExport = builder.prismaNode("ModelExport", { +export const Variable = builder.prismaNode("Variable", { id: { field: "id" }, fields: (t) => ({ modelRevision: t.relation("modelRevision"), @@ -46,13 +45,13 @@ export const ModelExport = builder.prismaNode("ModelExport", { }), }); -export const ModelExportConnection = builder.connectionObject({ - type: ModelExport, - name: "ModelExportConnection", +export const VariableConnection = builder.connectionObject({ + type: Variable, + name: "VariableConnection", }); -export const modelExportConnectionHelpers = prismaConnectionHelpers( +export const variableConnectionHelpers = prismaConnectionHelpers( builder, - "ModelExport", + "Variable", { cursor: "id" } ); diff --git a/packages/hub/src/lib/ExportsDropdown.tsx b/packages/hub/src/lib/VariablesDropdown.tsx similarity index 76% rename from packages/hub/src/lib/ExportsDropdown.tsx rename to packages/hub/src/lib/VariablesDropdown.tsx index d680b91132..a5b8811657 100644 --- a/packages/hub/src/lib/ExportsDropdown.tsx +++ b/packages/hub/src/lib/VariablesDropdown.tsx @@ -8,11 +8,11 @@ import { } from "@quri/ui"; import { DropdownMenuNextLinkItem } from "@/components/ui/DropdownMenuNextLinkItem"; -import { modelExportRoute, modelForRelativeValuesExportRoute } from "@/routes"; +import { modelForRelativeValuesExportRoute, variableRoute } from "@/routes"; import { exportTypeIcon } from "./typeIcon"; -export type ModelExport = { +export type Variable = { title?: string; variableName: string; variableType?: string; @@ -21,11 +21,11 @@ export type ModelExport = { type RelativeValuesExport = { slug: string; variableName: string }; -const nonRelativeValuesExports = ( - modelExports: ModelExport[], +const nonRelativeValuesVariables = ( + variables: Variable[], relativeValuesExports: RelativeValuesExport[] ) => - modelExports.filter( + variables.filter( (exportItem) => !relativeValuesExports.find( ({ variableName: v }) => v === exportItem.variableName @@ -34,33 +34,36 @@ const nonRelativeValuesExports = ( //It's a bit awkward that this here, but it's fairly closely coupled to ExportsDropdown. export const totalImportLength = ( - modelExports: ModelExport[], + variables: Variable[], relativeValuesExports: RelativeValuesExport[] ) => - nonRelativeValuesExports(modelExports, relativeValuesExports).length + + nonRelativeValuesVariables(variables, relativeValuesExports).length + relativeValuesExports.length; -export const ExportsDropdown: FC< +export const VariablesDropdown: FC< PropsWithChildren<{ - modelExports: ModelExport[]; + variables: Variable[]; relativeValuesExports: RelativeValuesExport[]; owner: string; slug: string; }> -> = ({ modelExports, relativeValuesExports, owner, slug, children }) => { - //We remove the relative values exports from the exports list, to not double count them. - const exports = nonRelativeValuesExports(modelExports, relativeValuesExports); +> = ({ variables, relativeValuesExports, owner, slug, children }) => { + //We remove the relative values variables from the exports list, to not double count them. + const _variables = nonRelativeValuesVariables( + variables, + relativeValuesExports + ); return ( ( - {exports.length > 0 && ( + {_variables.length > 0 && ( <> Exports - {exports.map((exportItem) => ( + {_variables.map((exportItem) => ( = ({ modelRef, showOwner = true }) => { slug: model.slug, }); - const modelExports = model.currentRevision.exports.map( + const modelVariables = model.currentRevision.variables.map( ({ variableName, variableType, title }) => ({ variableName, variableType, @@ -62,22 +62,22 @@ export const ModelCard: FC = ({ modelRef, showOwner = true }) => { ); const _totalImportLength = totalImportLength( - modelExports, + modelVariables, relativeValuesExports ); const footerItems = _totalImportLength > 0 ? ( -
- {`${_totalImportLength} exports`} + {`${_totalImportLength} variables`}
-
+ ) : undefined; return ( diff --git a/packages/hub/src/routes.ts b/packages/hub/src/routes.ts index 493690af21..977261b497 100644 --- a/packages/hub/src/routes.ts +++ b/packages/hub/src/routes.ts @@ -68,7 +68,7 @@ export function isModelRelativeValuesRoute(url: string) { return url.match("^/models/[^/]+/[^/]+/relative-values/[^/]+$"); } -export function modelExportRoute({ +export function variableRoute({ owner, modelSlug, variableName, @@ -78,7 +78,7 @@ export function modelExportRoute({ variableName: string; }) { const modelUrl = modelRoute({ owner, slug: modelSlug }); - return `${modelUrl}/exports/${variableName}`; + return `${modelUrl}/variables/${variableName}`; } export function modelViewRoute({ @@ -136,7 +136,7 @@ export function userGroupsRoute({ username }: { username: string }) { return `/users/${username}/groups`; } -export function userModelExportsRoute({ username }: { username: string }) { +export function userVariablesRoute({ username }: { username: string }) { return `/users/${username}/exports`; } diff --git a/packages/hub/src/scripts/buildRecentModelRevision/worker.ts b/packages/hub/src/scripts/buildRecentModelRevision/worker.ts index 30347ed95f..295d23efb9 100644 --- a/packages/hub/src/scripts/buildRecentModelRevision/worker.ts +++ b/packages/hub/src/scripts/buildRecentModelRevision/worker.ts @@ -1,5 +1,5 @@ import { runSquiggle } from "@/graphql/queries/runSquiggle"; -import { ModelExport } from "@/lib/ExportsDropdown"; +import { ModelExport } from "@/lib/VariablesDropdown"; import { prisma } from "@/prisma"; export type WorkerRunMessage = { diff --git a/packages/hub/src/modelExports/components/ModelExportCard.tsx b/packages/hub/src/variables/components/VariableCard.tsx similarity index 60% rename from packages/hub/src/modelExports/components/ModelExportCard.tsx rename to packages/hub/src/variables/components/VariableCard.tsx index 1fa11e177f..1310522640 100644 --- a/packages/hub/src/modelExports/components/ModelExportCard.tsx +++ b/packages/hub/src/variables/components/VariableCard.tsx @@ -7,12 +7,12 @@ import remarkGfm from "remark-gfm"; import { EntityCard } from "@/components/EntityCard"; import { exportTypeIcon } from "@/lib/typeIcon"; -import { modelExportRoute, modelRoute } from "@/routes"; +import { modelRoute, variableRoute } from "@/routes"; -import { ModelExportCard$key } from "@/__generated__/ModelExportCard.graphql"; +import { VariableCard$key } from "@/__generated__/VariableCard.graphql"; const Fragment = graphql` - fragment ModelExportCard on ModelExport { + fragment VariableCard on Variable { id variableName title @@ -31,18 +31,18 @@ const Fragment = graphql` `; type Props = { - modelExportRef: ModelExportCard$key; + variableRef: VariableCard$key; }; -export const ModelExportCard: FC = ({ modelExportRef }) => { - const modelExport = useFragment(Fragment, modelExportRef); +export const VariableCard: FC = ({ variableRef }) => { + const variable = useFragment(Fragment, variableRef); - const Icon = exportTypeIcon(modelExport.variableType); + const Icon = exportTypeIcon(variable.variableType); // This will have problems with markdown tags, but I looked into markdown-truncation packages, and they can get complicated. Will try this for now. const docstring = - (modelExport.docstring && - truncate(modelExport.docstring, { + (variable.docstring && + truncate(variable.docstring, { length: 500, separator: " ", omission: "...", @@ -51,28 +51,28 @@ export const ModelExportCard: FC = ({ modelExportRef }) => { return ( - {`${modelExport.owner.slug}/${modelExport.modelRevision.model.slug}`} + {`${variable.owner.slug}/${variable.modelRevision.model.slug}`}
- {modelExport.variableType} + {variable.variableType}
} diff --git a/packages/hub/src/modelExports/components/ModelExportList.tsx b/packages/hub/src/variables/components/VariableList.tsx similarity index 60% rename from packages/hub/src/modelExports/components/ModelExportList.tsx rename to packages/hub/src/variables/components/VariableList.tsx index 67bec8c867..b3e60b9b64 100644 --- a/packages/hub/src/modelExports/components/ModelExportList.tsx +++ b/packages/hub/src/variables/components/VariableList.tsx @@ -4,16 +4,16 @@ import { graphql, useFragment } from "react-relay"; import { LoadMore } from "@/components/LoadMore"; -import { ModelExportCard } from "./ModelExportCard"; +import { VariableCard } from "./VariableCard"; -import { ModelExportList$key } from "@/__generated__/ModelExportList.graphql"; +import { VariableList$key } from "@/__generated__/VariableList.graphql"; const Fragment = graphql` - fragment ModelExportList on ModelExportConnection { + fragment VariableList on VariableConnection { edges { node { id - ...ModelExportCard + ...VariableCard } } pageInfo { @@ -23,18 +23,18 @@ const Fragment = graphql` `; type Props = { - connectionRef: ModelExportList$key; + connectionRef: VariableList$key; loadNext(count: number): unknown; }; -export const ModelExportList: FC = ({ connectionRef, loadNext }) => { +export const VariableList: FC = ({ connectionRef, loadNext }) => { const connection = useFragment(Fragment, connectionRef); return (
{connection.edges.map((edge) => ( - + ))}
{connection.pageInfo.hasNextPage && } diff --git a/packages/hub/test/gql-gen/graphql.ts b/packages/hub/test/gql-gen/graphql.ts index 95b9ad36d8..135050c3b3 100644 --- a/packages/hub/test/gql-gen/graphql.ts +++ b/packages/hub/test/gql-gen/graphql.ts @@ -248,8 +248,8 @@ export type ModelEdge = { node: Model; }; -export type ModelExport = Node & { - __typename?: 'ModelExport'; +export type Variable = Node & { + __typename?: 'Variable'; docstring: Scalars['String']['output']; id: Scalars['ID']['output']; modelRevision: ModelRevision; @@ -264,7 +264,7 @@ export type ModelRevision = Node & { comment: Scalars['String']['output']; content: ModelContent; createdAtTimestamp: Scalars['Float']['output']; - exports: Array; + variables: Array; forRelativeValues?: Maybe; id: Scalars['ID']['output']; model: Model; @@ -626,7 +626,7 @@ export type MutationUpdateRelativeValuesDefinitionResult = BaseError | UpdateRel export type MutationUpdateSquiggleSnippetModelInput = { comment?: InputMaybe; content: SquiggleSnippetContentInput; - exports?: InputMaybe>; + variables?: InputMaybe>; owner: Scalars['String']['input']; relativeValuesExports?: InputMaybe>; slug: Scalars['String']['input']; @@ -800,7 +800,7 @@ export type RelativeValuesDefinition = Node & { currentRevision: RelativeValuesDefinitionRevision; id: Scalars['ID']['output']; isEditable: Scalars['Boolean']['output']; - modelExports: Array; + Variables: Array; owner: Owner; slug: Scalars['String']['output']; updatedAtTimestamp: Scalars['Float']['output']; @@ -876,7 +876,7 @@ export type SquiggleErrorOutput = SquiggleOutput & { isCached: Scalars['Boolean']['output']; }; -export type SquiggleModelExportInput = { +export type SquiggleVariableInput = { docstring?: InputMaybe; title?: InputMaybe; variableName: Scalars['String']['input']; From 273049487936e434ae45578ba43367292b055664 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 11 Apr 2024 19:32:29 -0700 Subject: [PATCH 02/16] Most renaming for /app files --- .../migration.sql | 11 ++- .../20240411205304_gs/migration.sql | 30 -------- .../migration.sql | 26 +++++++ packages/hub/prisma/schema.prisma | 15 +++- packages/hub/schema.graphql | 53 ++++++++----- .../hub/src/app/FrontPageVariableList.tsx | 4 +- .../[slug]/EditSquiggleSnippetModel.tsx | 4 +- .../app/models/[owner]/[slug]/ModelLayout.tsx | 22 +++--- .../[slug]/revisions/ModelRevisionsList.tsx | 18 +++-- .../[variableName]/SquiggleVariablePage.tsx} | 12 +-- .../[variableName]/VariablePage.tsx} | 77 ++++++++----------- .../[variableName]/page.tsx | 10 +-- packages/hub/src/graphql/queries/variable.ts | 33 ++++++++ packages/hub/src/graphql/queries/variables.ts | 16 +--- packages/hub/src/graphql/schema.ts | 1 + packages/hub/src/graphql/types/Group.ts | 10 +-- packages/hub/src/graphql/types/Model.ts | 46 +---------- .../hub/src/graphql/types/ModelRevision.ts | 2 +- packages/hub/src/graphql/types/User.ts | 23 +++--- packages/hub/src/graphql/types/Variable.ts | 52 +++++++++---- .../hub/src/graphql/types/VariableRevision.ts | 27 +++++++ .../hub/src/models/components/ModelCard.tsx | 20 ++--- .../src/variables/components/VariableCard.tsx | 27 ++++--- .../src/variables/components/VariableList.tsx | 2 +- 24 files changed, 294 insertions(+), 247 deletions(-) delete mode 100644 packages/hub/prisma/migrations/20240411205304_gs/migration.sql create mode 100644 packages/hub/prisma/migrations/20240412000612_variable_table/migration.sql rename packages/hub/src/app/models/[owner]/[slug]/{exports/[variableName]/SquiggleModelExportPage.tsx => variables/[variableName]/SquiggleVariablePage.tsx} (85%) rename packages/hub/src/app/models/[owner]/[slug]/{exports/[variableName]/ModelExportPage.tsx => variables/[variableName]/VariablePage.tsx} (58%) rename packages/hub/src/app/models/[owner]/[slug]/{exports => variables}/[variableName]/page.tsx (60%) create mode 100644 packages/hub/src/graphql/queries/variable.ts create mode 100644 packages/hub/src/graphql/types/VariableRevision.ts diff --git a/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql b/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql index f5d9bf03ce..ad1233740e 100644 --- a/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql +++ b/packages/hub/prisma/migrations/20240411205141_model_export_to_variable/migration.sql @@ -1,10 +1,9 @@ ALTER TABLE "ModelExport" DROP CONSTRAINT "ModelExport_modelRevisionId_fkey"; --- RenameTable -ALTER TABLE "ModelExport" RENAME TO "VariableExportRevision"; +ALTER TABLE "ModelExport" RENAME TO "VariableRevision"; --- RenameIndex -ALTER INDEX "ModelExport_modelRevisionId_variableName_key" RENAME TO "VariableExportRevision_modelRevisionId_variableName_key"; +ALTER INDEX "ModelExport_modelRevisionId_variableName_key" RENAME TO "VariableRevision_modelRevisionId_variableName_key"; --- AddForeignKey -ALTER TABLE "VariableExportRevision" ADD CONSTRAINT "VariableExportRevision_modelRevisionId_fkey" FOREIGN KEY ("modelRevisionId") REFERENCES "ModelRevision"("id") ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file +ALTER TABLE "VariableRevision" ADD CONSTRAINT "VariableRevision_modelRevisionId_fkey" FOREIGN KEY ("modelRevisionId") REFERENCES "ModelRevision"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "VariableRevision" RENAME CONSTRAINT "ModelExport_pkey" TO "VariableRevision_pkey"; \ No newline at end of file diff --git a/packages/hub/prisma/migrations/20240411205304_gs/migration.sql b/packages/hub/prisma/migrations/20240411205304_gs/migration.sql deleted file mode 100644 index 310b9c9a45..0000000000 --- a/packages/hub/prisma/migrations/20240411205304_gs/migration.sql +++ /dev/null @@ -1,30 +0,0 @@ -/* - Warnings: - - - You are about to drop the `VariableExportRevision` table. If the table is not empty, all the data it contains will be lost. - -*/ --- DropForeignKey -ALTER TABLE "VariableExportRevision" DROP CONSTRAINT "VariableExportRevision_modelRevisionId_fkey"; - --- DropTable -DROP TABLE "VariableExportRevision"; - --- CreateTable -CREATE TABLE "Variable" ( - "id" TEXT NOT NULL, - "modelRevisionId" TEXT NOT NULL, - "variableName" TEXT NOT NULL, - "title" TEXT, - "docstring" TEXT NOT NULL DEFAULT '', - "variableType" TEXT NOT NULL DEFAULT 'OTHER', - "isCurrent" BOOLEAN NOT NULL DEFAULT false, - - CONSTRAINT "Variable_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "Variable_modelRevisionId_variableName_key" ON "Variable"("modelRevisionId", "variableName"); - --- AddForeignKey -ALTER TABLE "Variable" ADD CONSTRAINT "Variable_modelRevisionId_fkey" FOREIGN KEY ("modelRevisionId") REFERENCES "ModelRevision"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/hub/prisma/migrations/20240412000612_variable_table/migration.sql b/packages/hub/prisma/migrations/20240412000612_variable_table/migration.sql new file mode 100644 index 0000000000..e001921cf2 --- /dev/null +++ b/packages/hub/prisma/migrations/20240412000612_variable_table/migration.sql @@ -0,0 +1,26 @@ +/* + Warnings: + + - Added the required column `variableId` to the `VariableRevision` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "VariableRevision" ADD COLUMN "variableId" TEXT NOT NULL; + +-- CreateTable +CREATE TABLE "Variable" ( + "id" TEXT NOT NULL, + "variableName" TEXT NOT NULL, + "modelId" TEXT NOT NULL, + + CONSTRAINT "Variable_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Variable_modelId_variableName_key" ON "Variable"("modelId", "variableName"); + +-- AddForeignKey +ALTER TABLE "Variable" ADD CONSTRAINT "Variable_modelId_fkey" FOREIGN KEY ("modelId") REFERENCES "Model"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "VariableRevision" ADD CONSTRAINT "VariableRevision_variableId_fkey" FOREIGN KEY ("variableId") REFERENCES "Variable"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/hub/prisma/schema.prisma b/packages/hub/prisma/schema.prisma index 2c7010f8d0..ecf0dc3574 100644 --- a/packages/hub/prisma/schema.prisma +++ b/packages/hub/prisma/schema.prisma @@ -194,6 +194,7 @@ model Model { currentRevisionId String? @unique searchable Searchable? + variables Variable[] @@unique([slug, ownerId]) @@index([createdAt]) @@ -219,7 +220,7 @@ model ModelRevision { contentId String? @unique relativeValuesExports RelativeValuesExport[] - variables Variable[] + variableRevisions VariableRevision[] // required by Prisma, but unused since `model` field should point at the same entity currentRevisionModel Model? @relation("CurrentRevision") @@ -253,9 +254,21 @@ model SquiggleSnippet { } model Variable { + id String @id @default(cuid()) + variableName String + model Model @relation(fields: [modelId], references: [id], onDelete: Cascade) + modelId String + revisions VariableRevision[] + + @@unique([modelId, variableName], name: "uniqueKey") +} + +model VariableRevision { id String @id @default(cuid()) modelRevision ModelRevision @relation(fields: [modelRevisionId], references: [id], onDelete: Cascade) modelRevisionId String + variable Variable @relation(fields: [variableId], references: [id], onDelete: Cascade) + variableId String variableName String title String? docstring String @default("") diff --git a/packages/hub/schema.graphql b/packages/hub/schema.graphql index 2dc4edabeb..f71cf54e14 100644 --- a/packages/hub/schema.graphql +++ b/packages/hub/schema.graphql @@ -90,7 +90,7 @@ type Group implements Node & Owner { inviteForMe: GroupInvite invites(after: String, before: String, first: Int, last: Int): GroupInviteConnection memberships(after: String, before: String, first: Int, last: Int): UserGroupMembershipConnection! - modelExports(after: String, before: String, first: Int, last: Int): Variable! + modelExports(after: String, before: String, first: Int, last: Int): VariableRevision! models(after: String, before: String, first: Int, last: Int): ModelConnection! myMembership: UserGroupMembership reusableInviteToken: String @@ -153,7 +153,6 @@ enum MembershipRole { type Model implements Node { createdAtTimestamp: Float! currentRevision: ModelRevision! - exportRevisions(after: String, before: String, first: Int, last: Int, variableId: String!): ModelExportRevisionsConnection! id: ID! isEditable: Boolean! isPrivate: Boolean! @@ -163,6 +162,7 @@ type Model implements Node { revisions(after: String, before: String, first: Int, last: Int): ModelRevisionConnection! slug: String! updatedAtTimestamp: Float! + variables: [Variable!]! } type ModelConnection { @@ -177,16 +177,6 @@ type ModelEdge { node: Model! } -type ModelExportRevisionsConnection { - edges: [ModelExportRevisionsConnectionEdge!]! - pageInfo: PageInfo! -} - -type ModelExportRevisionsConnectionEdge { - cursor: String! - node: Variable! -} - type ModelRevision implements Node { author: User buildStatus: ModelRevisionBuildStatus! @@ -199,7 +189,7 @@ type ModelRevision implements Node { lastBuild: ModelRevisionBuild model: Model! relativeValuesExports: [RelativeValuesExport!]! - variables: [Variable!]! + variableRevisions: [VariableRevision!]! } type ModelRevisionBuild implements Node { @@ -527,6 +517,7 @@ type Query { search(after: String, before: String, first: Int, last: Int, text: String!): QuerySearchResult! userByUsername(username: String!): QueryUserByUsernameResult! users(after: String, before: String, first: Int, input: UsersQueryInput, last: Int): QueryUsersConnection! + variable(input: QueryVariableInput!): QueryVariableResult! variables(after: String, before: String, first: Int, input: VariableQueryInput, last: Int): VariableConnection! } @@ -565,6 +556,13 @@ type QueryUsersConnectionEdge { node: User! } +input QueryVariableInput { + modelId: String! + variableName: String! +} + +union QueryVariableResult = BaseError | NotFoundError | Variable + type ReactToGroupInviteResult { invite: GroupInvite! membership: UserGroupMembership @@ -779,14 +777,12 @@ type ValidationErrorIssue { } type Variable implements Node { - docstring: String! id: ID! - isCurrent: Boolean! - modelRevision: ModelRevision! + lastRevision: VariableRevision + model: Model! owner: Owner! - title: String + revisions(after: String, before: String, first: Int, last: Int): VariableRevisionConnection! variableName: String! - variableType: String! } type VariableConnection { @@ -803,4 +799,25 @@ input VariableQueryInput { modelId: String owner: String variableName: String +} + +type VariableRevision implements Node { + docstring: String! + id: ID! + isCurrent: Boolean! + modelRevision: ModelRevision! + title: String + variable: Variable! + variableName: String! + variableType: String! +} + +type VariableRevisionConnection { + edges: [VariableRevisionEdge!]! + pageInfo: PageInfo! +} + +type VariableRevisionEdge { + cursor: String! + node: VariableRevision! } \ No newline at end of file diff --git a/packages/hub/src/app/FrontPageVariableList.tsx b/packages/hub/src/app/FrontPageVariableList.tsx index 1859369ae9..d31749e805 100644 --- a/packages/hub/src/app/FrontPageVariableList.tsx +++ b/packages/hub/src/app/FrontPageVariableList.tsx @@ -5,6 +5,9 @@ import { graphql, usePaginationFragment } from "react-relay"; import { VariableList } from "@/variables/components/VariableList"; +import { FrontPageVariableList$key } from "@/__generated__/FrontPageVariableList.graphql"; +import { FrontPageVariableListPaginationQuery } from "@/__generated__/FrontPageVariableListPaginationQuery.graphql"; + const Fragment = graphql` fragment FrontPageVariableList on Query @argumentDefinitions( @@ -14,7 +17,6 @@ const Fragment = graphql` @refetchable(queryName: "FrontPageVariableListPaginationQuery") { variables(first: $count, after: $cursor) @connection(key: "FrontPageVariableList_variables") { - # necessary for Relay edges { __typename } diff --git a/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx b/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx index 5c27a9e63b..ecb0d3da37 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/EditSquiggleSnippetModel.tsx @@ -162,11 +162,11 @@ export const EditSquiggleSnippetModel: FC = ({ } } exportNames - variables { + variableRevisions { id variableName - variableType title + variableType docstring } relativeValuesExports { diff --git a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx index a98f1ca3e6..bf59cea703 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx @@ -46,16 +46,18 @@ const Query = graphql` ...FixModelUrlCasing ...ModelAccessControls ...ModelSettingsButton - currentRevision { + variables { id - # for length; TODO - "hasExports" field? - exportNames - variables { - id - variableName + variableName + lastRevision { variableType title } + } + currentRevision { + id + # for length; TODO - "hasExports" field? + exportNames relativeValuesExports { id variableName @@ -87,14 +89,12 @@ export const ModelLayout: FC< }); const variable: Variable[] = model.currentRevision.exportNames.map((name) => { - const matchingExport = model.currentRevision.exports.find( - (e) => e.variableName === name - ); + const matchingExport = model.variables.find((e) => e.variableName === name); return { variableName: name, - variableType: matchingExport?.variableType || undefined, - title: matchingExport?.title || undefined, + variableType: matchingExport?.lastRevision?.variableType || undefined, + title: matchingExport?.lastRevision?.title || undefined, }; }); diff --git a/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx b/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx index 539d310cd4..04dee3cd98 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx @@ -32,10 +32,12 @@ const ModelRevisionItem: FC<{ username } comment - variables { + variableRevisions { id - variableName title + variable { + variableName + } } lastBuild { errors @@ -86,9 +88,9 @@ const ModelRevisionItem: FC<{ {revision.lastBuild && (
{`Build Time: ${revision.lastBuild.runSeconds.toFixed(2)}s`}
)} - {revision.variables.length > 0 ? ( + {revision.variableRevisions.length > 0 ? (
- {`${revision.variables.length} exports `} + {`${revision.variableRevisions.length} exports `}
) : null}
@@ -135,10 +137,12 @@ export const ModelRevisionsList: FC<{ id createdAtTimestamp buildStatus - variables { - id + variableRevisions { title - variableName + variable { + id + variableName + } } lastBuild { errors diff --git a/packages/hub/src/app/models/[owner]/[slug]/exports/[variableName]/SquiggleModelExportPage.tsx b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx similarity index 85% rename from packages/hub/src/app/models/[owner]/[slug]/exports/[variableName]/SquiggleModelExportPage.tsx rename to packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx index eacbc2542c..b0e87e2511 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/exports/[variableName]/SquiggleModelExportPage.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx @@ -11,7 +11,7 @@ import { import { squiggleHubLinker } from "@/squiggle/components/linker"; -import { SquiggleModelExportPage$key } from "@/__generated__/SquiggleModelExportPage.graphql"; +import { SquiggleVariablePage$key } from "@/__generated__/SquiggleVariablePage.graphql"; type SquiggleProps = { variableName: string; @@ -23,7 +23,7 @@ type GuardedType = T extends (x: any) => x is infer T ? T : never; type SupportedVersion = GuardedType<(typeof versionSupportsExports)["plain"]>; -const VersionedSquiggleModelExportPage: FC< +const VersionedSquiggleVariablePage: FC< SquiggleProps & { version: SupportedVersion; } @@ -53,13 +53,13 @@ const VersionedSquiggleModelExportPage: FC< ); }; -export const SquiggleModelExportPage: FC<{ +export const SquiggleVariablePage: FC<{ variableName: string; - contentRef: SquiggleModelExportPage$key; + contentRef: SquiggleVariablePage$key; }> = ({ variableName, contentRef }) => { const content = useFragment( graphql` - fragment SquiggleModelExportPage on SquiggleSnippet { + fragment SquiggleVariablePage on SquiggleSnippet { id code version @@ -79,7 +79,7 @@ export const SquiggleModelExportPage: FC<{ } return ( - void; loadNext?: (count: number) => void; -}> = ({ exportRevisions, selected, changeId, loadNext }) => { +}> = ({ revisions, selected, changeId, loadNext }) => { return (

Revisions

@@ -134,20 +130,6 @@ export const ModelRevisionsList: FC<{ edges { node { ...ModelRevisionsList_revision - id - createdAtTimestamp - buildStatus - variableRevisions { - title - variable { - id - variableName - } - } - lastBuild { - errors - runSeconds - } } } pageInfo { diff --git a/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariableRevisionPage.tsx similarity index 84% rename from packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx rename to packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariableRevisionPage.tsx index b0e87e2511..673ef22504 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariablePage.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/SquiggleVariableRevisionPage.tsx @@ -11,7 +11,7 @@ import { import { squiggleHubLinker } from "@/squiggle/components/linker"; -import { SquiggleVariablePage$key } from "@/__generated__/SquiggleVariablePage.graphql"; +import { SquiggleVariableRevisionPage$key } from "@/__generated__/SquiggleVariableRevisionPage.graphql"; type SquiggleProps = { variableName: string; @@ -23,7 +23,7 @@ type GuardedType = T extends (x: any) => x is infer T ? T : never; type SupportedVersion = GuardedType<(typeof versionSupportsExports)["plain"]>; -const VersionedSquiggleVariablePage: FC< +const VersionedSquiggleVariableRevisionPage: FC< SquiggleProps & { version: SupportedVersion; } @@ -53,13 +53,13 @@ const VersionedSquiggleVariablePage: FC< ); }; -export const SquiggleVariablePage: FC<{ +export const SquiggleVariableRevisionPage: FC<{ variableName: string; - contentRef: SquiggleVariablePage$key; + contentRef: SquiggleVariableRevisionPage$key; }> = ({ variableName, contentRef }) => { const content = useFragment( graphql` - fragment SquiggleVariablePage on SquiggleSnippet { + fragment SquiggleVariableRevisionPage on SquiggleSnippet { id code version @@ -79,7 +79,7 @@ export const SquiggleVariablePage: FC<{ } return ( -
- void; @@ -90,12 +89,12 @@ const CreateVariableWithDefinitionModal: FC<{ const ExportItem: FC<{ item: RelativeValuesExportInput; - modelRef: EditVariables_Model$key; + modelRef: EditRelativeValueExports_Model$key; remove: () => void; }> = ({ item, modelRef, remove }) => { const model = useFragment( graphql` - fragment EditVariables_Model on Model { + fragment EditRelativeValueExports_Model on Model { id slug owner { @@ -139,10 +138,10 @@ type Props = { append: (item: RelativeValuesExportInput) => void; remove: (id: number) => void; items: RelativeValuesExportInput[]; - modelRef: EditVariables_Model$key; + modelRef: EditRelativeValueExports_Model$key; }; -export const EditVariables: FC = ({ +export const EditRelativeValueExports: FC = ({ append, remove, items, @@ -165,7 +164,7 @@ export const EditVariables: FC = ({
{isOpen && ( From cb3b0e37321acc462db5f355d0fee786132eb8bc Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Apr 2024 15:44:03 -0700 Subject: [PATCH 11/16] Fixed VariablePage to not throw error when variable is not made --- .../[slug]/revisions/ModelRevisionsList.tsx | 1 + .../variables/[variableName]/VariablePage.tsx | 71 +++++++++++-------- .../exports/EditRelativeValueExports.tsx | 1 + 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx b/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx index efa7e5b138..8a15c45798 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/revisions/ModelRevisionsList.tsx @@ -129,6 +129,7 @@ export const ModelRevisionsList: FC<{ @connection(key: "ModelRevisionsList_revisions") { edges { node { + id ...ModelRevisionsList_revision } } diff --git a/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/VariablePage.tsx b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/VariablePage.tsx index dd00f74756..f9fd323b06 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/VariablePage.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/variables/[variableName]/VariablePage.tsx @@ -3,6 +3,7 @@ import clsx from "clsx"; import { format } from "date-fns"; import { FC, useState } from "react"; import { graphql, usePaginationFragment } from "react-relay"; +import { FragmentRefs } from "relay-runtime"; import { LoadMore } from "@/components/LoadMore"; import { extractFromGraphqlErrorUnion } from "@/lib/graphqlHelpers"; @@ -52,34 +53,15 @@ const VariableRevisionsPanel: FC<{ ); }; -export const VariablePage: FC<{ - params: { - owner: string; - slug: string; - variableName: string; +export const VariablePageBody: FC<{ + variableName: string; + result: { + readonly __typename: "Variable"; + readonly id: string; + readonly variableName: string; + readonly " $fragmentSpreads": FragmentRefs<"VariablePage">; }; - query: SerializablePreloadedQuery; -}> = ({ query, params }) => { - const [{ variable: result }] = usePageQuery( - graphql` - query VariablePageQuery($input: QueryVariableInput!) { - variable(input: $input) { - __typename - ... on Variable { - id - variableName - ...VariablePage - } - } - } - `, - query - ); - - if (result.__typename !== "Variable") { - return
No revisions found. They should be built shortly.
; - } - +}> = ({ result, variableName }) => { const variable = extractFromGraphqlErrorUnion(result, "Variable"); const { @@ -137,7 +119,7 @@ export const VariablePage: FC<{
@@ -155,3 +137,36 @@ export const VariablePage: FC<{ } } }; + +export const VariablePage: FC<{ + params: { + owner: string; + slug: string; + variableName: string; + }; + query: SerializablePreloadedQuery; +}> = ({ query, params }) => { + const [{ variable: result }] = usePageQuery( + graphql` + query VariablePageQuery($input: QueryVariableInput!) { + variable(input: $input) { + __typename + ... on Variable { + id + variableName + ...VariablePage + } + } + } + `, + query + ); + + if (result.__typename !== "Variable") { + return
No revisions found. They should be built shortly.
; + } + + return ( + + ); +}; diff --git a/packages/hub/src/components/exports/EditRelativeValueExports.tsx b/packages/hub/src/components/exports/EditRelativeValueExports.tsx index e8f7ef1070..a914c18290 100644 --- a/packages/hub/src/components/exports/EditRelativeValueExports.tsx +++ b/packages/hub/src/components/exports/EditRelativeValueExports.tsx @@ -20,6 +20,7 @@ import { SelectRelativeValuesDefinitionOption, } from "./SelectRelativeValuesDefinition"; +import { EditRelativeValueExports_Model$key } from "@/__generated__/EditRelativeValueExports_Model.graphql"; import { RelativeValuesExportInput } from "@/__generated__/EditSquiggleSnippetModelMutation.graphql"; const CreateVariableWithDefinitionModal: FC<{ From ea61de165d12f24c0acff8008a9ae5888299a8d8 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Apr 2024 16:54:53 -0700 Subject: [PATCH 12/16] Minor rename --- packages/hub/src/lib/VariablesDropdown.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hub/src/lib/VariablesDropdown.tsx b/packages/hub/src/lib/VariablesDropdown.tsx index bf47f6e04f..146191c947 100644 --- a/packages/hub/src/lib/VariablesDropdown.tsx +++ b/packages/hub/src/lib/VariablesDropdown.tsx @@ -49,7 +49,7 @@ export const VariablesDropdown: FC< }> > = ({ variableRevisions, relativeValuesExports, owner, slug, children }) => { //We remove the relative values variables from the exports list, to not double count them. - const _variableRevisions = nonRelativeValuesVariables( + const allExports = nonRelativeValuesVariables( variableRevisions, relativeValuesExports ); @@ -57,10 +57,10 @@ export const VariablesDropdown: FC< ( - {_variableRevisions.length > 0 && ( + {allExports.length > 0 && ( <> Exported Variables - {_variableRevisions.map((exportItem) => ( + {allExports.map((exportItem) => ( Date: Fri, 12 Apr 2024 17:14:18 -0700 Subject: [PATCH 13/16] Fixed variable query --- packages/hub/src/graphql/queries/variables.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/hub/src/graphql/queries/variables.ts b/packages/hub/src/graphql/queries/variables.ts index bf2a91966c..d85d62649c 100644 --- a/packages/hub/src/graphql/queries/variables.ts +++ b/packages/hub/src/graphql/queries/variables.ts @@ -1,5 +1,3 @@ -import merge from "lodash/merge"; - import { builder } from "@/graphql/builder"; import { prisma } from "@/prisma"; @@ -25,18 +23,14 @@ builder.queryField("variables", (t) => resolve: (query, _, { input }, { session }) => { const modelId = input?.modelId; - const queries = merge( - {}, - { model: modelWhereHasAccess(session) }, - modelId && { modelId: modelId }, - input?.owner && { - model: { owner: { slug: input.owner } }, + const queries = { + model: { + ...modelWhereHasAccess(session), + ...(input?.owner && { owner: { slug: input.owner } }), }, - input && - input.variableName && { - variableName: input.variableName, - } - ); + ...(modelId && { modelId: modelId }), + ...(input?.variableName && { variableName: input.variableName }), + }; return prisma.variable.findMany({ ...query, From 6c4719534cb655abd68fc482b70e1187db22f09e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Apr 2024 17:39:41 -0700 Subject: [PATCH 14/16] Minor style changes to exports --- packages/hub/src/components/EntityCard.tsx | 6 +++--- packages/hub/src/variables/components/VariableCard.tsx | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/hub/src/components/EntityCard.tsx b/packages/hub/src/components/EntityCard.tsx index 939f848920..07e8b17f97 100644 --- a/packages/hub/src/components/EntityCard.tsx +++ b/packages/hub/src/components/EntityCard.tsx @@ -39,7 +39,7 @@ export const EntityCard: FC = ({ }) => { return ( -
+
= ({ {slug}
- {children &&
{children}
} -
+ {
{children}
} +
{footerItems} {isPrivate && }
diff --git a/packages/hub/src/variables/components/VariableCard.tsx b/packages/hub/src/variables/components/VariableCard.tsx index 6f6fdd47b3..358ede6b63 100644 --- a/packages/hub/src/variables/components/VariableCard.tsx +++ b/packages/hub/src/variables/components/VariableCard.tsx @@ -29,6 +29,7 @@ const Fragment = graphql` } model { slug + isPrivate } } `; @@ -67,6 +68,7 @@ export const VariableCard: FC = ({ variableRef }) => { owner: variable.owner.slug, })} showOwner={false} + isPrivate={variable.model.isPrivate} slug={variable.lastRevision?.title || variable.variableName} footerItems={ <> From 37c31daa2440d38ab858f37c098083e998c7f013 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Fri, 12 Apr 2024 19:36:56 -0700 Subject: [PATCH 15/16] Added Variable currentRevision --- .../migration.sql | 14 +++++ packages/hub/prisma/schema.prisma | 11 +++- packages/hub/schema.graphql | 3 +- .../app/models/[owner]/[slug]/ModelLayout.tsx | 7 +-- packages/hub/src/graphql/queries/variables.ts | 6 +++ packages/hub/src/graphql/types/Variable.ts | 21 +------- .../hub/src/graphql/types/VariableRevision.ts | 52 +++++++++++++++++++ .../hub/src/models/components/ModelCard.tsx | 2 +- .../scripts/buildRecentModelRevision/main.ts | 35 ++----------- .../buildRecentModelRevision/worker.ts | 6 +-- .../src/variables/components/VariableCard.tsx | 18 +++---- 11 files changed, 105 insertions(+), 70 deletions(-) create mode 100644 packages/hub/prisma/migrations/20240413012803_variable_current_revision_id/migration.sql diff --git a/packages/hub/prisma/migrations/20240413012803_variable_current_revision_id/migration.sql b/packages/hub/prisma/migrations/20240413012803_variable_current_revision_id/migration.sql new file mode 100644 index 0000000000..31c84eebe4 --- /dev/null +++ b/packages/hub/prisma/migrations/20240413012803_variable_current_revision_id/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - A unique constraint covering the columns `[currentRevisionId]` on the table `Variable` will be added. If there are existing duplicate values, this will fail. + +*/ +-- AlterTable +ALTER TABLE "Variable" ADD COLUMN "currentRevisionId" TEXT; + +-- CreateIndex +CREATE UNIQUE INDEX "Variable_currentRevisionId_key" ON "Variable"("currentRevisionId"); + +-- AddForeignKey +ALTER TABLE "Variable" ADD CONSTRAINT "Variable_currentRevisionId_fkey" FOREIGN KEY ("currentRevisionId") REFERENCES "VariableRevision"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/hub/prisma/schema.prisma b/packages/hub/prisma/schema.prisma index 84a9d103d7..df98921e92 100644 --- a/packages/hub/prisma/schema.prisma +++ b/packages/hub/prisma/schema.prisma @@ -258,7 +258,11 @@ model Variable { variableName String model Model @relation(fields: [modelId], references: [id], onDelete: Cascade) modelId String - revisions VariableRevision[] + revisions VariableRevision[] @relation("Revisions") + + // technically nullable, but won't ever be null in practice + currentRevision VariableRevision? @relation("CurrentRevision", fields: [currentRevisionId], references: [id]) + currentRevisionId String? @unique @@unique([modelId, variableName]) } @@ -267,13 +271,16 @@ model VariableRevision { id String @id @default(cuid()) modelRevision ModelRevision @relation(fields: [modelRevisionId], references: [id], onDelete: Cascade) modelRevisionId String - variable Variable @relation(fields: [variableId], references: [id], onDelete: Cascade) + variable Variable @relation("Revisions", fields: [variableId], references: [id], onDelete: Cascade) variableId String variableName String title String? docstring String @default("") variableType String @default("OTHER") + // required by Prisma, but unused since `model` field should point at the same entity + currentRevisionVariable Variable? @relation("CurrentRevision") + @@unique([modelRevisionId, variableName]) } diff --git a/packages/hub/schema.graphql b/packages/hub/schema.graphql index 7433266322..add529deeb 100644 --- a/packages/hub/schema.graphql +++ b/packages/hub/schema.graphql @@ -778,8 +778,8 @@ type ValidationErrorIssue { } type Variable implements Node { + currentRevision: VariableRevision id: ID! - lastRevision: VariableRevision model: Model! owner: Owner! revisions(after: String, before: String, first: Int, last: Int): VariableRevisionConnection! @@ -800,6 +800,7 @@ input VariableQueryInput { modelId: String owner: String variableName: String + variableType: String } type VariableRevision implements Node { diff --git a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx index 0b96477395..728f534127 100644 --- a/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx +++ b/packages/hub/src/app/models/[owner]/[slug]/ModelLayout.tsx @@ -49,7 +49,7 @@ const Query = graphql` variables { id variableName - lastRevision { + currentRevision { variableType title } @@ -95,8 +95,9 @@ export const ModelLayout: FC< return { variableName: name, - variableType: matchingVariable?.lastRevision?.variableType || undefined, - title: matchingVariable?.lastRevision?.title || undefined, + variableType: + matchingVariable?.currentRevision?.variableType || undefined, + title: matchingVariable?.currentRevision?.title || undefined, }; }); diff --git a/packages/hub/src/graphql/queries/variables.ts b/packages/hub/src/graphql/queries/variables.ts index d85d62649c..7470053ef9 100644 --- a/packages/hub/src/graphql/queries/variables.ts +++ b/packages/hub/src/graphql/queries/variables.ts @@ -9,6 +9,7 @@ const VariableQueryInput = builder.inputType("VariableQueryInput", { modelId: t.string(), variableName: t.string(), owner: t.string(), + variableType: t.string(), }), }); @@ -30,6 +31,11 @@ builder.queryField("variables", (t) => }, ...(modelId && { modelId: modelId }), ...(input?.variableName && { variableName: input.variableName }), + ...(input?.variableType && { + currentRevision: { + variableType: input.variableType, + }, + }), }; return prisma.variable.findMany({ diff --git a/packages/hub/src/graphql/types/Variable.ts b/packages/hub/src/graphql/types/Variable.ts index 1ca5f6047e..0660d46231 100644 --- a/packages/hub/src/graphql/types/Variable.ts +++ b/packages/hub/src/graphql/types/Variable.ts @@ -3,10 +3,7 @@ import { prismaConnectionHelpers } from "@pothos/plugin-prisma"; import { builder } from "@/graphql/builder"; import { Owner } from "./Owner"; -import { - VariableRevision, - VariableRevisionConnection, -} from "./VariableRevision"; +import { VariableRevisionConnection } from "./VariableRevision"; export const Variable = builder.prismaNode("Variable", { id: { field: "id" }, @@ -53,22 +50,8 @@ export const Variable = builder.prismaNode("Variable", { }, VariableRevisionConnection ), - lastRevision: t.field({ - type: VariableRevision, + currentRevision: t.relation("currentRevision", { nullable: true, - select: { - revisions: { - orderBy: { - modelRevision: { - createdAt: "desc", - }, - }, - take: 1, - }, - }, - async resolve(variable) { - return variable.revisions[0]; - }, }), }), }); diff --git a/packages/hub/src/graphql/types/VariableRevision.ts b/packages/hub/src/graphql/types/VariableRevision.ts index d2149c8a96..397575fa16 100644 --- a/packages/hub/src/graphql/types/VariableRevision.ts +++ b/packages/hub/src/graphql/types/VariableRevision.ts @@ -1,6 +1,7 @@ import { prismaConnectionHelpers } from "@pothos/plugin-prisma"; import { builder } from "@/graphql/builder"; +import { prisma } from "@/prisma"; export const VariableRevision = builder.prismaNode("VariableRevision", { id: { field: "id" }, @@ -24,3 +25,54 @@ export const VariableRevisionConnection = builder.connectionObject({ type: VariableRevision, name: "VariableRevisionConnection", }); + +export type VariableRevisionInput = { + title?: string; + variableName: string; + variableType?: string; + docstring?: string; +}; + +export async function createVariableRevision( + modelId: string, + revisionId: string, + variableData: VariableRevisionInput +) { + const variable = await prisma.variable.findFirst({ + where: { + modelId: modelId, + variableName: variableData.variableName, + }, + }); + + let variableId: string; + if (!variable) { + const createdVariable = await prisma.variable.create({ + data: { + model: { connect: { id: modelId } }, + variableName: variableData.variableName, + }, + }); + variableId = createdVariable.id; + } else { + variableId = variable.id; + } + + const createdVariableRevision = await prisma.variableRevision.create({ + data: { + variableName: variableData.variableName, + variable: { connect: { id: variableId } }, + modelRevision: { connect: { id: revisionId } }, + variableType: variableData.variableType, + title: variableData.title, + docstring: variableData.docstring, + }, + }); + + await prisma.variable.update({ + where: { id: variableId }, + data: { + currentRevisionId: createdVariableRevision.id, + }, + }); +} diff --git a/packages/hub/src/models/components/ModelCard.tsx b/packages/hub/src/models/components/ModelCard.tsx index 64041cd71f..5ef468a11b 100644 --- a/packages/hub/src/models/components/ModelCard.tsx +++ b/packages/hub/src/models/components/ModelCard.tsx @@ -23,7 +23,7 @@ const Fragment = graphql` isPrivate variables { variableName - lastRevision { + currentRevision { variableType title } diff --git a/packages/hub/src/scripts/buildRecentModelRevision/main.ts b/packages/hub/src/scripts/buildRecentModelRevision/main.ts index 5519dba399..617135f088 100644 --- a/packages/hub/src/scripts/buildRecentModelRevision/main.ts +++ b/packages/hub/src/scripts/buildRecentModelRevision/main.ts @@ -1,6 +1,8 @@ import { PrismaClient } from "@prisma/client"; import { spawn } from "child_process"; +import { createVariableRevision } from "@/graphql/types/VariableRevision"; + import { NotFoundError } from "../../graphql/errors/NotFoundError"; import { WorkerOutput, WorkerRunMessage } from "./worker"; @@ -137,38 +139,7 @@ async function buildRecentModelVersion(): Promise { }); for (const e of response.variableRevisions) { - const variable = await tx.variable.findFirst({ - where: { - modelId: modelId, - variableName: e.variableName, - }, - }); - - let createdVariableId: string | undefined = undefined; - - if (!variable) { - // Create a new Variable if it doesn't exist - const createdVariable = await tx.variable.create({ - data: { - model: { connect: { id: modelId } }, - variableName: e.variableName, - }, - }); - createdVariableId = createdVariable.id; - } - - const variableId = variable?.id || createdVariableId!; - - await tx.variableRevision.create({ - data: { - variableName: e.variableName, - variable: { connect: { id: variableId } }, - modelRevision: { connect: { id: revisionId } }, - variableType: e.variableType, - title: e.title, - docstring: e.docstring, - }, - }); + createVariableRevision(modelId, revisionId, e); } }); console.log( diff --git a/packages/hub/src/scripts/buildRecentModelRevision/worker.ts b/packages/hub/src/scripts/buildRecentModelRevision/worker.ts index 85b8b65299..ce4b9825aa 100644 --- a/packages/hub/src/scripts/buildRecentModelRevision/worker.ts +++ b/packages/hub/src/scripts/buildRecentModelRevision/worker.ts @@ -1,5 +1,5 @@ import { runSquiggle } from "@/graphql/queries/runSquiggle"; -import { VariableRevision } from "@/lib/VariablesDropdown"; +import { VariableRevisionInput } from "@/graphql/types/VariableRevision"; import { prisma } from "@/prisma"; export type WorkerRunMessage = { @@ -12,7 +12,7 @@ export type WorkerRunMessage = { export type WorkerOutput = { errors: string; - variableRevisions: VariableRevision[]; + variableRevisions: VariableRevisionInput[]; }; export async function runSquiggleCode( @@ -21,7 +21,7 @@ export async function runSquiggleCode( ): Promise { const outputR = await runSquiggle(code, seed); - let variableRevisions: VariableRevision[] = []; + let variableRevisions: VariableRevisionInput[] = []; if (outputR.ok) { // I Imagine it would be nice to move this out of this worker file, but this would require exporting a lot more information. It seems wise to instead wait for the Serialization PR to go in and then refactor this. diff --git a/packages/hub/src/variables/components/VariableCard.tsx b/packages/hub/src/variables/components/VariableCard.tsx index 358ede6b63..9b02ca53e5 100644 --- a/packages/hub/src/variables/components/VariableCard.tsx +++ b/packages/hub/src/variables/components/VariableCard.tsx @@ -15,7 +15,7 @@ const Fragment = graphql` fragment VariableCard on Variable { id variableName - lastRevision { + currentRevision { id title docstring @@ -41,18 +41,18 @@ type Props = { export const VariableCard: FC = ({ variableRef }) => { const variable = useFragment(Fragment, variableRef); - const lastRevision = variable.lastRevision; + const currentRevision = variable.currentRevision; - if (!lastRevision) { + if (!currentRevision) { return null; } - const Icon = exportTypeIcon(lastRevision.variableType || ""); + const Icon = exportTypeIcon(currentRevision.variableType || ""); // This will have problems with markdown tags, but I looked into markdown-truncation packages, and they can get complicated. Will try this for now. const docstring = - (lastRevision.docstring && - truncate(lastRevision.docstring, { + (currentRevision.docstring && + truncate(currentRevision.docstring, { length: 500, separator: " ", omission: "...", @@ -61,7 +61,7 @@ export const VariableCard: FC = ({ variableRef }) => { return ( = ({ variableRef }) => { })} showOwner={false} isPrivate={variable.model.isPrivate} - slug={variable.lastRevision?.title || variable.variableName} + slug={variable.currentRevision?.title || variable.variableName} footerItems={ <> = ({ variableRef }) => {
- {lastRevision.variableType} + {currentRevision.variableType}
} From 38c52bea195c688b976466290630ea98a69cb98d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 13 Apr 2024 08:32:01 -0700 Subject: [PATCH 16/16] Fixed builds --- .../hub/src/app/api/updateModelSeeds/route.ts | 80 ------------------- .../hub/src/models/components/ModelCard.tsx | 4 +- 2 files changed, 2 insertions(+), 82 deletions(-) delete mode 100644 packages/hub/src/app/api/updateModelSeeds/route.ts diff --git a/packages/hub/src/app/api/updateModelSeeds/route.ts b/packages/hub/src/app/api/updateModelSeeds/route.ts deleted file mode 100644 index b454ccc1dd..0000000000 --- a/packages/hub/src/app/api/updateModelSeeds/route.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { PrismaClient } from "@prisma/client"; -import { NextRequest, NextResponse } from "next/server"; - -import { generateSeed } from "@quri/squiggle-lang"; - -const prisma = new PrismaClient(); - -async function updateSquiggleSnippetsSeedForModels() { - // Retrieve all models - const models = await prisma.model.findMany({ - include: { - revisions: { - include: { - squiggleSnippet: true, - }, - orderBy: { - createdAt: "desc", - }, - take: 1, - }, - }, - }); - - for (const model of models) { - const lastRevision = model.revisions[0]; - - // Check if the last revision's SquiggleSnippet has the DEFAULT_SEED - if ( - lastRevision.squiggleSnippet && - lastRevision.squiggleSnippet.seed === "DEFAULT_SEED" - ) { - const newSeed = generateSeed(); - - // Update all SquiggleSnippets for all revisions of the current model - for (const revision of model.revisions) { - if (revision.squiggleSnippet) { - await prisma.squiggleSnippet.update({ - where: { - id: revision.squiggleSnippet.id, - }, - data: { - seed: newSeed, - }, - }); - } - } - } - } -} - -export async function POST(req: NextRequest) { - const adminToken = req.headers.get("x-admin-token"); - const secretToken = process.env["ADMIN_SECRET_TOKEN"]; - - if (!secretToken || adminToken !== secretToken) { - return new NextResponse(null, { - status: 401, - statusText: "Unauthorized access.", - }); - } - - try { - await updateSquiggleSnippetsSeedForModels(); - return new NextResponse( - JSON.stringify({ - message: - "Successfully updated seeds for models where the last revision had DEFAULT_SEED.", - }), - { status: 200 } - ); - } catch (error) { - console.error("An error occurred:", error); - return new NextResponse( - JSON.stringify({ - error: "An error occurred while updating seeds.", - }), - { status: 500 } - ); - } -} diff --git a/packages/hub/src/models/components/ModelCard.tsx b/packages/hub/src/models/components/ModelCard.tsx index 5ef468a11b..d4a4c8d5f4 100644 --- a/packages/hub/src/models/components/ModelCard.tsx +++ b/packages/hub/src/models/components/ModelCard.tsx @@ -54,8 +54,8 @@ export const ModelCard: FC = ({ modelRef, showOwner = true }) => { const variableRevisions: VariableRevision[] = model.variables.map((v) => ({ variableName: v.variableName, - variableType: v.lastRevision?.variableType, - title: v.lastRevision?.title || undefined, + variableType: v.currentRevision?.variableType, + title: v.currentRevision?.title || undefined, docString: undefined, }));