From 0d8cf29a668885ba8f38f2832e448dcf1a2fec3e Mon Sep 17 00:00:00 2001 From: andrewwallacespeckle Date: Fri, 25 Jul 2025 15:40:55 +0100 Subject: [PATCH] feat(fe): new models panel first draft --- .../components/global/icon/Minus.vue | 17 ++ .../components/global/icon/Plus.vue | 15 +- .../components/global/icon/Versions.vue | 23 +- .../frontend-2/components/viewer/Models.vue | 229 +++++++++++++++ .../components/viewer/ModelsCard.vue | 265 ++++++++++++++++++ .../frontend-2/components/viewer/Versions.vue | 93 ++++++ .../components/viewer/VersionsCard.vue | 232 +++++++++++++++ .../components/viewer/controls/Left.vue | 34 +-- .../components/viewer/explorer/TreeItem.vue | 175 +++++------- .../components/viewer/layout/SidePanel.vue | 57 +--- .../components/viewer/resources/List.vue | 19 +- .../lib/common/generated/gql/gql.ts | 12 +- .../lib/common/generated/gql/graphql.ts | 4 +- .../lib/viewer/helpers/shortcuts/shortcuts.ts | 10 +- 14 files changed, 990 insertions(+), 195 deletions(-) create mode 100644 packages/frontend-2/components/global/icon/Minus.vue create mode 100644 packages/frontend-2/components/viewer/Models.vue create mode 100644 packages/frontend-2/components/viewer/ModelsCard.vue create mode 100644 packages/frontend-2/components/viewer/Versions.vue create mode 100644 packages/frontend-2/components/viewer/VersionsCard.vue diff --git a/packages/frontend-2/components/global/icon/Minus.vue b/packages/frontend-2/components/global/icon/Minus.vue new file mode 100644 index 000000000..9b135e287 --- /dev/null +++ b/packages/frontend-2/components/global/icon/Minus.vue @@ -0,0 +1,17 @@ + diff --git a/packages/frontend-2/components/global/icon/Plus.vue b/packages/frontend-2/components/global/icon/Plus.vue index dc55f009c..bc9cded2e 100644 --- a/packages/frontend-2/components/global/icon/Plus.vue +++ b/packages/frontend-2/components/global/icon/Plus.vue @@ -6,6 +6,19 @@ fill="none" xmlns="http://www.w3.org/2000/svg" > - + + diff --git a/packages/frontend-2/components/global/icon/Versions.vue b/packages/frontend-2/components/global/icon/Versions.vue index 53a8acb0f..a309ff40a 100644 --- a/packages/frontend-2/components/global/icon/Versions.vue +++ b/packages/frontend-2/components/global/icon/Versions.vue @@ -7,10 +7,25 @@ xmlns="http://www.w3.org/2000/svg" > + + diff --git a/packages/frontend-2/components/viewer/Models.vue b/packages/frontend-2/components/viewer/Models.vue new file mode 100644 index 000000000..3f37c46c7 --- /dev/null +++ b/packages/frontend-2/components/viewer/Models.vue @@ -0,0 +1,229 @@ + + + diff --git a/packages/frontend-2/components/viewer/ModelsCard.vue b/packages/frontend-2/components/viewer/ModelsCard.vue new file mode 100644 index 000000000..b230fed35 --- /dev/null +++ b/packages/frontend-2/components/viewer/ModelsCard.vue @@ -0,0 +1,265 @@ + + + + diff --git a/packages/frontend-2/components/viewer/Versions.vue b/packages/frontend-2/components/viewer/Versions.vue new file mode 100644 index 000000000..7316e4258 --- /dev/null +++ b/packages/frontend-2/components/viewer/Versions.vue @@ -0,0 +1,93 @@ + + + diff --git a/packages/frontend-2/components/viewer/VersionsCard.vue b/packages/frontend-2/components/viewer/VersionsCard.vue new file mode 100644 index 000000000..76c553590 --- /dev/null +++ b/packages/frontend-2/components/viewer/VersionsCard.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/packages/frontend-2/components/viewer/controls/Left.vue b/packages/frontend-2/components/viewer/controls/Left.vue index f373336eb..62b918bdb 100644 --- a/packages/frontend-2/components/viewer/controls/Left.vue +++ b/packages/frontend-2/components/viewer/controls/Left.vue @@ -17,24 +17,9 @@ - - - - - @@ -93,24 +78,25 @@ > - - - - - - + + + + + ) @@ -210,7 +196,7 @@ const { summary } = useFunctionRunsStatusSummary({ registerShortcuts({ ToggleModels: () => toggleActivePanel('models'), - ToggleExplorer: () => toggleActivePanel('explorer'), + ToggleFilters: () => toggleActivePanel('filters'), ToggleDiscussions: () => toggleActivePanel('discussions') }) diff --git a/packages/frontend-2/components/viewer/explorer/TreeItem.vue b/packages/frontend-2/components/viewer/explorer/TreeItem.vue index 86e25658a..f4ba21f62 100644 --- a/packages/frontend-2/components/viewer/explorer/TreeItem.vue +++ b/packages/frontend-2/components/viewer/explorer/TreeItem.vue @@ -1,97 +1,86 @@ + diff --git a/packages/frontend-2/components/viewer/resources/List.vue b/packages/frontend-2/components/viewer/resources/List.vue index b59cad825..7e50fe89d 100644 --- a/packages/frontend-2/components/viewer/resources/List.vue +++ b/packages/frontend-2/components/viewer/resources/List.vue @@ -1,20 +1,22 @@ +
+ +

No models loaded, yet.

+ Add model +
diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts index 91e5b7a8a..3ddfed9b7 100644 --- a/packages/frontend-2/lib/common/generated/gql/gql.ts +++ b/packages/frontend-2/lib/common/generated/gql/gql.ts @@ -155,13 +155,13 @@ type Documents = { "\n fragment SettingsWorkspacesSecurityWorkspaceCreation_Workspace on Workspace {\n id\n slug\n role\n isExclusive\n hasAccessToExclusiveMembership: hasAccessToFeature(featureName: exclusiveMembership)\n permissions {\n canMakeWorkspaceExclusive {\n authorized\n message\n }\n }\n }\n": typeof types.SettingsWorkspacesSecurityWorkspaceCreation_WorkspaceFragmentDoc, "\n fragment SettingsWorkspacesSecuritySsoWrapper_Workspace on Workspace {\n id\n role\n slug\n sso {\n provider {\n id\n name\n clientId\n issuerUrl\n }\n }\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": typeof types.SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragmentDoc, "\n fragment ModelPageProject on Project {\n id\n createdAt\n name\n visibility\n workspace {\n id\n slug\n name\n role\n }\n embedOptions {\n hideSpeckleBranding\n }\n hasAccessToFeature(featureName: hideSpeckleBranding)\n ...ViewerLimitsDialog_Project\n }\n": typeof types.ModelPageProjectFragmentDoc, + "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n": typeof types.ViewerModelVersionCardItemFragmentDoc, "\n fragment ViewerCommentThreadData on Comment {\n id\n permissions {\n canArchive {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ViewerCommentThreadDataFragmentDoc, "\n fragment ThreadCommentAttachment on Comment {\n text {\n attachments {\n id\n fileName\n fileType\n fileSize\n }\n }\n }\n": typeof types.ThreadCommentAttachmentFragmentDoc, "\n fragment ViewerCommentsListItem on Comment {\n id\n rawText\n archived\n author {\n ...LimitedUserAvatar\n }\n createdAt\n viewedAt\n replies {\n totalCount\n cursor\n items {\n ...ViewerCommentsReplyItem\n }\n }\n replyAuthors(limit: 4) {\n totalCount\n items {\n ...FormUsersSelectItem\n }\n }\n resources {\n resourceId\n resourceType\n }\n }\n": typeof types.ViewerCommentsListItemFragmentDoc, "\n fragment ViewerLimitsDialog_Project on Project {\n id\n workspaceId\n ...ViewerLimitsWorkspaceDialog_Project\n ...WorkspaceMoveProject_Project\n }\n": typeof types.ViewerLimitsDialog_ProjectFragmentDoc, "\n fragment ViewerLimitsWorkspaceDialog_Project on Project {\n id\n workspace {\n id\n role\n slug\n ...WorkspacePlanLimits_Workspace\n }\n ...UseLoadLatestVersion_Project\n }\n": typeof types.ViewerLimitsWorkspaceDialog_ProjectFragmentDoc, "\n fragment ViewerResourcesLimitAlert_Project on Project {\n id\n workspaceId\n workspace {\n id\n slug\n ...ViewerResourcesWorkspaceLimitAlert_Workspace\n }\n ...WorkspaceMoveProject_Project\n }\n": typeof types.ViewerResourcesLimitAlert_ProjectFragmentDoc, - "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n": typeof types.ViewerModelVersionCardItemFragmentDoc, "\n fragment ViewerResourcesPersonalLimitAlert_Project on Project {\n id\n ...WorkspaceMoveProject_Project\n }\n": typeof types.ViewerResourcesPersonalLimitAlert_ProjectFragmentDoc, "\n fragment ViewerResourcesWorkspaceLimitAlert_Workspace on Workspace {\n id\n slug\n }\n": typeof types.ViewerResourcesWorkspaceLimitAlert_WorkspaceFragmentDoc, "\n fragment WorkspaceAddProjectMenu_Workspace on Workspace {\n id\n name\n slug\n role\n plan {\n name\n }\n permissions {\n canCreateProject {\n ...FullPermissionCheckResult\n }\n canMoveProjectToWorkspace {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsAdd_Workspace\n ...WorkspaceMoveProject_Workspace\n ...UseCanCreateWorkspaceProject_Workspace\n ...UseCanMoveProjectIntoWorkspace_Workspace\n }\n": typeof types.WorkspaceAddProjectMenu_WorkspaceFragmentDoc, @@ -624,13 +624,13 @@ const documents: Documents = { "\n fragment SettingsWorkspacesSecurityWorkspaceCreation_Workspace on Workspace {\n id\n slug\n role\n isExclusive\n hasAccessToExclusiveMembership: hasAccessToFeature(featureName: exclusiveMembership)\n permissions {\n canMakeWorkspaceExclusive {\n authorized\n message\n }\n }\n }\n": types.SettingsWorkspacesSecurityWorkspaceCreation_WorkspaceFragmentDoc, "\n fragment SettingsWorkspacesSecuritySsoWrapper_Workspace on Workspace {\n id\n role\n slug\n sso {\n provider {\n id\n name\n clientId\n issuerUrl\n }\n }\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": types.SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragmentDoc, "\n fragment ModelPageProject on Project {\n id\n createdAt\n name\n visibility\n workspace {\n id\n slug\n name\n role\n }\n embedOptions {\n hideSpeckleBranding\n }\n hasAccessToFeature(featureName: hideSpeckleBranding)\n ...ViewerLimitsDialog_Project\n }\n": types.ModelPageProjectFragmentDoc, + "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n": types.ViewerModelVersionCardItemFragmentDoc, "\n fragment ViewerCommentThreadData on Comment {\n id\n permissions {\n canArchive {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ViewerCommentThreadDataFragmentDoc, "\n fragment ThreadCommentAttachment on Comment {\n text {\n attachments {\n id\n fileName\n fileType\n fileSize\n }\n }\n }\n": types.ThreadCommentAttachmentFragmentDoc, "\n fragment ViewerCommentsListItem on Comment {\n id\n rawText\n archived\n author {\n ...LimitedUserAvatar\n }\n createdAt\n viewedAt\n replies {\n totalCount\n cursor\n items {\n ...ViewerCommentsReplyItem\n }\n }\n replyAuthors(limit: 4) {\n totalCount\n items {\n ...FormUsersSelectItem\n }\n }\n resources {\n resourceId\n resourceType\n }\n }\n": types.ViewerCommentsListItemFragmentDoc, "\n fragment ViewerLimitsDialog_Project on Project {\n id\n workspaceId\n ...ViewerLimitsWorkspaceDialog_Project\n ...WorkspaceMoveProject_Project\n }\n": types.ViewerLimitsDialog_ProjectFragmentDoc, "\n fragment ViewerLimitsWorkspaceDialog_Project on Project {\n id\n workspace {\n id\n role\n slug\n ...WorkspacePlanLimits_Workspace\n }\n ...UseLoadLatestVersion_Project\n }\n": types.ViewerLimitsWorkspaceDialog_ProjectFragmentDoc, "\n fragment ViewerResourcesLimitAlert_Project on Project {\n id\n workspaceId\n workspace {\n id\n slug\n ...ViewerResourcesWorkspaceLimitAlert_Workspace\n }\n ...WorkspaceMoveProject_Project\n }\n": types.ViewerResourcesLimitAlert_ProjectFragmentDoc, - "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n": types.ViewerModelVersionCardItemFragmentDoc, "\n fragment ViewerResourcesPersonalLimitAlert_Project on Project {\n id\n ...WorkspaceMoveProject_Project\n }\n": types.ViewerResourcesPersonalLimitAlert_ProjectFragmentDoc, "\n fragment ViewerResourcesWorkspaceLimitAlert_Workspace on Workspace {\n id\n slug\n }\n": types.ViewerResourcesWorkspaceLimitAlert_WorkspaceFragmentDoc, "\n fragment WorkspaceAddProjectMenu_Workspace on Workspace {\n id\n name\n slug\n role\n plan {\n name\n }\n permissions {\n canCreateProject {\n ...FullPermissionCheckResult\n }\n canMoveProjectToWorkspace {\n ...FullPermissionCheckResult\n }\n }\n ...ProjectsAdd_Workspace\n ...WorkspaceMoveProject_Workspace\n ...UseCanCreateWorkspaceProject_Workspace\n ...UseCanMoveProjectIntoWorkspace_Workspace\n }\n": types.WorkspaceAddProjectMenu_WorkspaceFragmentDoc, @@ -1530,6 +1530,10 @@ export function graphql(source: "\n fragment SettingsWorkspacesSecuritySsoWrapp * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n fragment ModelPageProject on Project {\n id\n createdAt\n name\n visibility\n workspace {\n id\n slug\n name\n role\n }\n embedOptions {\n hideSpeckleBranding\n }\n hasAccessToFeature(featureName: hideSpeckleBranding)\n ...ViewerLimitsDialog_Project\n }\n"): (typeof documents)["\n fragment ModelPageProject on Project {\n id\n createdAt\n name\n visibility\n workspace {\n id\n slug\n name\n role\n }\n embedOptions {\n hideSpeckleBranding\n }\n hasAccessToFeature(featureName: hideSpeckleBranding)\n ...ViewerLimitsDialog_Project\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n"): (typeof documents)["\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -1554,10 +1558,6 @@ export function graphql(source: "\n fragment ViewerLimitsWorkspaceDialog_Projec * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n fragment ViewerResourcesLimitAlert_Project on Project {\n id\n workspaceId\n workspace {\n id\n slug\n ...ViewerResourcesWorkspaceLimitAlert_Workspace\n }\n ...WorkspaceMoveProject_Project\n }\n"): (typeof documents)["\n fragment ViewerResourcesLimitAlert_Project on Project {\n id\n workspaceId\n workspace {\n id\n slug\n ...ViewerResourcesWorkspaceLimitAlert_Workspace\n }\n ...WorkspaceMoveProject_Project\n }\n"]; -/** - * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function graphql(source: "\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n"): (typeof documents)["\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/frontend-2/lib/common/generated/gql/graphql.ts b/packages/frontend-2/lib/common/generated/gql/graphql.ts index df41f0abe..2272d5b1c 100644 --- a/packages/frontend-2/lib/common/generated/gql/graphql.ts +++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts @@ -5694,6 +5694,8 @@ export type SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragment = { __typenam export type ModelPageProjectFragment = { __typename?: 'Project', id: string, createdAt: string, name: string, visibility: ProjectVisibility, hasAccessToFeature: boolean, workspaceId?: string | null, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, role?: string | null, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null } | null, embedOptions: { __typename?: 'ProjectEmbedOptions', hideSpeckleBranding: boolean }, permissions: { __typename?: 'ProjectPermissionChecks', canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }; +export type ViewerModelVersionCardItemFragment = { __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }; + export type ViewerCommentThreadDataFragment = { __typename?: 'Comment', id: string, permissions: { __typename?: 'CommentPermissionChecks', canArchive: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }; export type ThreadCommentAttachmentFragment = { __typename?: 'Comment', text?: { __typename?: 'SmartTextEditorValue', attachments?: Array<{ __typename?: 'BlobMetadata', id: string, fileName: string, fileType: string, fileSize?: number | null }> | null } | null }; @@ -5706,8 +5708,6 @@ export type ViewerLimitsWorkspaceDialog_ProjectFragment = { __typename?: 'Projec export type ViewerResourcesLimitAlert_ProjectFragment = { __typename?: 'Project', id: string, workspaceId?: string | null, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null, permissions: { __typename?: 'ProjectPermissionChecks', canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }; -export type ViewerModelVersionCardItemFragment = { __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }; - export type ViewerResourcesPersonalLimitAlert_ProjectFragment = { __typename?: 'Project', id: string, workspaceId?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }; export type ViewerResourcesWorkspaceLimitAlert_WorkspaceFragment = { __typename?: 'Workspace', id: string, slug: string }; diff --git a/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts index 8d18b3220..a1081a1e5 100644 --- a/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts +++ b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts @@ -9,12 +9,12 @@ export const PanelShortcuts = { key: 'M', action: 'ToggleModels' }, - ToggleExplorer: { - name: 'Scene explorer', - description: 'Toggle scene explorer panel', + ToggleFilters: { + name: 'Filters', + description: 'Toggle filters panel', modifiers: [ModifierKeys.Shift], - key: 'E', - action: 'ToggleExplorer' + key: 'F', + action: 'ToggleFilters' }, ToggleDiscussions: { name: 'Discussions',