From 21e4598556c7ecf7d71ed96c9704ec7d1adcee92 Mon Sep 17 00:00:00 2001 From: andrewwallacespeckle Date: Fri, 14 Mar 2025 15:35:15 +0000 Subject: [PATCH 01/11] refactor(fe): simplify planPlan to always use monthly price --- .../workspaces/billing/PricingTable/Plan.vue | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/frontend-2/components/settings/workspaces/billing/PricingTable/Plan.vue b/packages/frontend-2/components/settings/workspaces/billing/PricingTable/Plan.vue index 72e6528a2..b70582d23 100644 --- a/packages/frontend-2/components/settings/workspaces/billing/PricingTable/Plan.vue +++ b/packages/frontend-2/components/settings/workspaces/billing/PricingTable/Plan.vue @@ -13,7 +13,7 @@

- {{ formatPrice(finalPlanPrice) }} + {{ formatPrice(planPrice?.['workspace:member']) }} per seat/month

@@ -136,19 +136,7 @@ const isUpgradeDialogOpen = ref(false) const isYearlyIntervalSelected = ref(props.yearlyIntervalSelected) const planFeatures = computed(() => WorkspacePlanConfigs[props.plan].features) -const planPrice = computed( - () => - prices.value?.[props.plan]?.[props.yearlyIntervalSelected ? 'yearly' : 'monthly'] -) - -const finalPlanPrice = computed(() => { - const basePrice = prices.value?.[props.plan].monthly?.['workspace:member'] - if (!basePrice) return undefined - return { - ...basePrice, - amount: props.yearlyIntervalSelected ? basePrice.amount * 0.8 : basePrice.amount - } -}) +const planPrice = computed(() => prices.value?.[props.plan]?.monthly) const hasCta = computed(() => !!slots.cta) const canUpgradeToPlan = computed(() => { From 6e170d0c4faea5480846e925771da3cb9e781c81 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Sat, 15 Mar 2025 10:43:40 +0000 Subject: [PATCH 02/11] fix(docker compose): preview service can be used with docker compose --- docker-compose-speckle.yml | 23 ++++-- .../server/modules/previews/rest/router.ts | 8 +- .../modules/shared/helpers/envHelper.ts | 75 +++++++++---------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/docker-compose-speckle.yml b/docker-compose-speckle.yml index d1f6790f9..446204c58 100644 --- a/docker-compose-speckle.yml +++ b/docker-compose-speckle.yml @@ -1,4 +1,3 @@ -version: '2.4' services: speckle-ingress: build: @@ -22,12 +21,16 @@ services: restart: always environment: NUXT_PUBLIC_SERVER_NAME: 'local' + #TODO: Change this to the URL of your server. This is the URL of the server as accessed by users. NUXT_PUBLIC_API_ORIGIN: 'http://127.0.0.1' + #TODO: Change this to the URL of your server. This is the URL of the server as accessed by users. NUXT_PUBLIC_BASE_URL: 'http://127.0.0.1' + # This is the URL of the server as accessed via this docker compose network. NUXT_PUBLIC_BACKEND_API_ORIGIN: 'http://speckle-server:3000' NUXT_PUBLIC_LOG_LEVEL: 'warn' NUXT_REDIS_URL: 'redis://redis' LOG_LEVEL: 'info' + LOG_PRETTY: 'true' speckle-server: build: @@ -47,14 +50,20 @@ services: retries: 3 start_period: 90s environment: - # TODO: Change this to the URL of the speckle server, as accessed from the network + # TODO. Change this to the url of your server. This is the URL of the server as accessed by users. CANONICAL_URL: 'http://127.0.0.1' + # This is the URL of the server as accessed by other Speckle services within this docker compose network, such as preview-service. + # This will be the same value as NUXT_PUBLIC_BACKEND_API_ORIGIN as defined in the frontend-2 service. + PRIVATE_SERVER_URL: 'http://speckle-server:3000' # TODO: Change this to a unique secret for this server SESSION_SECRET: 'TODO:Replace' + # This is the authentication strategy to use. Local (i.e. username & password) is the default strategy. STRATEGY_LOCAL: 'true' + LOG_LEVEL: 'info' + LOG_PRETTY: 'true' POSTGRES_URL: 'postgres' POSTGRES_USER: 'speckle' @@ -62,6 +71,7 @@ services: POSTGRES_DB: 'speckle' REDIS_URL: 'redis://redis' + PREVIEW_SERVICE_REDIS_URL: 'redis://redis' S3_ENDPOINT: 'http://minio:9000' S3_ACCESS_KEY: 'minioadmin' @@ -85,10 +95,11 @@ services: mem_limit: '3000m' memswap_limit: '3000m' environment: - HOST: '127.0.0.1' # Only accept connections from localhost, as preview service does not need to be exposed outside the container. - METRICS_HOST: '127.0.0.1' # Amend if you want to expose Prometheus metrics outside of the container + HOST: '127.0.0.1' # The preview service does not need to be exposed outside the container. + PORT: '3001' LOG_LEVEL: 'info' - PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' + LOG_PRETTY: 'true' + REDIS_URL: 'redis://redis' webhook-service: build: @@ -99,6 +110,7 @@ services: restart: always environment: LOG_LEVEL: 'info' + LOG_PRETTY: 'true' PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' fileimport-service: @@ -110,6 +122,7 @@ services: restart: always environment: LOG_LEVEL: 'info' + LOG_PRETTY: 'true' PG_CONNECTION_STRING: 'postgres://speckle:speckle@postgres/speckle' SPECKLE_SERVER_URL: 'http://speckle-server:3000' FILE_IMPORT_TIME_LIMIT_MIN: 10 diff --git a/packages/server/modules/previews/rest/router.ts b/packages/server/modules/previews/rest/router.ts index 964b7279b..92374d73b 100644 --- a/packages/server/modules/previews/rest/router.ts +++ b/packages/server/modules/previews/rest/router.ts @@ -37,7 +37,10 @@ import { storeTokenScopesFactory, storeUserServerAppTokenFactory } from '@/modules/core/repositories/tokens' -import { getServerOrigin } from '@/modules/shared/helpers/envHelper' +import { + getPrivateServerOrigin, + getServerOrigin +} from '@/modules/shared/helpers/envHelper' import { requestObjectPreviewFactory } from '@/modules/previews/queues/previews' import type { Queue } from 'bull' import type { Knex } from 'knex' @@ -61,7 +64,8 @@ const buildCreateObjectPreviewFunction = ({ queue: previewRequestQueue, responseQueue: responseQueueName }), - serverOrigin: getServerOrigin(), + // use the private server origin if defined, otherwise use the public server origin + serverOrigin: getPrivateServerOrigin() || getServerOrigin(), storeObjectPreview: storeObjectPreviewFactory({ db: projectDb }), getStreamCollaborators: getStreamCollaboratorsFactory({ db }), createAppToken: createAppTokenFactory({ diff --git a/packages/server/modules/shared/helpers/envHelper.ts b/packages/server/modules/shared/helpers/envHelper.ts index 7303fd2c0..9d398f0d9 100644 --- a/packages/server/modules/shared/helpers/envHelper.ts +++ b/packages/server/modules/shared/helpers/envHelper.ts @@ -1,7 +1,7 @@ import { MisconfiguredEnvironmentError } from '@/modules/shared/errors' import { trimEnd } from 'lodash' import * as Environment from '@speckle/shared/dist/commonjs/environment/index.js' -import { ensureError } from '@speckle/shared' +import { ensureError, Nullable } from '@speckle/shared' export function getStringFromEnv( envVarKey: string, @@ -28,6 +28,32 @@ export function getBooleanFromEnv(envVarKey: string, aDefault = false): boolean return ['1', 'true', true].includes(process.env[envVarKey] || aDefault.toString()) } +function mustGetUrlFromEnv(name: string, trimTrailingSlash: boolean = false): URL { + const url = getUrlFromEnv(name, trimTrailingSlash) + if (!url) throw new MisconfiguredEnvironmentError(`${name} env var not configured`) + return url +} + +function getUrlFromEnv( + name: string, + trimTrailingSlash: boolean = false +): Nullable { + const value = process.env[name] + if (!value) { + return null + } + try { + return new URL(trimTrailingSlash ? trimEnd(value, '/') : value) + } catch (e: unknown) { + const err = ensureError(e, 'Unknown error parsing URL') + if (err instanceof TypeError && err.message === 'Invalid URL') + throw new MisconfiguredEnvironmentError(`${name} has to be a valid URL`, { + cause: err + }) + throw new MisconfiguredEnvironmentError(`Error parsing ${name} URL`, { cause: err }) + } +} + export function getSessionSecret() { if (!process.env.SESSION_SECRET) { throw new MisconfiguredEnvironmentError('SESSION_SECRET env var not configured') @@ -198,29 +224,16 @@ export function getFrontendOrigin() { * Get server app origin/base URL */ export function getServerOrigin() { - if (!process.env.CANONICAL_URL) { - throw new MisconfiguredEnvironmentError( - 'Server origin environment variable (CANONICAL_URL) not configured' - ) - } + return mustGetUrlFromEnv('CANONICAL_URL', true).origin +} +export function getPrivateServerOrigin() { try { - return new URL(trimEnd(process.env.CANONICAL_URL, '/')).origin - } catch (e) { - const err = ensureError(e) - if (e instanceof TypeError && e.message === 'Invalid URL') { - throw new MisconfiguredEnvironmentError( - `Server origin environment variable (CANONICAL_URL) is not a valid URL: ${process.env.CANONICAL_URL} ${err.message}`, - { - cause: e, - info: { - value: process.env.CANONICAL_URL - } - } - ) - } - - throw err + const url = getUrlFromEnv('PRIVATE_SERVER_URL', true) + if (!url) return url + return url.origin + } catch { + return null } } @@ -239,26 +252,12 @@ export function isSSLServer() { return /^https:\/\//.test(getServerOrigin()) } -function parseUrlVar(value: string, name: string) { - try { - return new URL(value) - } catch (err: unknown) { - if (err instanceof TypeError && err.message === 'Invalid URL') - throw new MisconfiguredEnvironmentError(`${name} has to be a valid URL`) - throw err - } -} - export function getServerMovedFrom() { - const value = process.env.MIGRATION_SERVER_MOVED_FROM - if (!value) return value - return parseUrlVar(value, 'MIGRATION_SERVER_MOVED_FROM') + return getUrlFromEnv('MIGRATION_SERVER_MOVED_FROM') } export function getServerMovedTo() { - const value = process.env.MIGRATION_SERVER_MOVED_TO - if (!value) return value - return parseUrlVar(value, 'MIGRATION_SERVER_MOVED_TO') + return getUrlFromEnv('MIGRATION_SERVER_MOVED_TO') } export function adminOverrideEnabled() { From 2dc32094d0e2e2e3112e2237e257910c2c741322 Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Sat, 15 Mar 2025 11:31:40 +0000 Subject: [PATCH 03/11] feat(helm chart): can be configured to deploy preview service in cluster --- docker-compose-speckle.yml | 3 ++- .../server/modules/previews/rest/router.ts | 9 +++++--- .../modules/shared/helpers/envHelper.ts | 21 +++++++++++-------- .../speckle-server/templates/_helpers.tpl | 11 +++++++++- .../templates/preview_service/deployment.yml | 3 ++- .../preview_service/networkpolicy.cilium.yml | 2 ++ .../networkpolicy.kubernetes.yml | 4 +++- .../templates/preview_service/service.yml | 2 ++ .../preview_service/serviceaccount.yml | 2 ++ utils/helm/speckle-server/values.schema.json | 5 +++++ utils/helm/speckle-server/values.yaml | 2 ++ 11 files changed, 48 insertions(+), 16 deletions(-) diff --git a/docker-compose-speckle.yml b/docker-compose-speckle.yml index 446204c58..658d2ccc2 100644 --- a/docker-compose-speckle.yml +++ b/docker-compose-speckle.yml @@ -54,7 +54,7 @@ services: CANONICAL_URL: 'http://127.0.0.1' # This is the URL of the server as accessed by other Speckle services within this docker compose network, such as preview-service. # This will be the same value as NUXT_PUBLIC_BACKEND_API_ORIGIN as defined in the frontend-2 service. - PRIVATE_SERVER_URL: 'http://speckle-server:3000' + PRIVATE_OBJECTS_SERVER_URL: 'http://speckle-server:3000' # TODO: Change this to a unique secret for this server SESSION_SECRET: 'TODO:Replace' @@ -71,6 +71,7 @@ services: POSTGRES_DB: 'speckle' REDIS_URL: 'redis://redis' + PREVIEW_SERVICE_USE_PRIVATE_OBJECTS_SERVER_URL: 'true' PREVIEW_SERVICE_REDIS_URL: 'redis://redis' S3_ENDPOINT: 'http://minio:9000' diff --git a/packages/server/modules/previews/rest/router.ts b/packages/server/modules/previews/rest/router.ts index 92374d73b..ea2002154 100644 --- a/packages/server/modules/previews/rest/router.ts +++ b/packages/server/modules/previews/rest/router.ts @@ -38,8 +38,9 @@ import { storeUserServerAppTokenFactory } from '@/modules/core/repositories/tokens' import { - getPrivateServerOrigin, - getServerOrigin + getPrivateObjectsServerOrigin, + getServerOrigin, + previewServiceShouldUsePrivateObjectsServerUrl } from '@/modules/shared/helpers/envHelper' import { requestObjectPreviewFactory } from '@/modules/previews/queues/previews' import type { Queue } from 'bull' @@ -65,7 +66,9 @@ const buildCreateObjectPreviewFunction = ({ responseQueue: responseQueueName }), // use the private server origin if defined, otherwise use the public server origin - serverOrigin: getPrivateServerOrigin() || getServerOrigin(), + serverOrigin: previewServiceShouldUsePrivateObjectsServerUrl() + ? getPrivateObjectsServerOrigin() + : getServerOrigin(), storeObjectPreview: storeObjectPreviewFactory({ db: projectDb }), getStreamCollaborators: getStreamCollaboratorsFactory({ db }), createAppToken: createAppTokenFactory({ diff --git a/packages/server/modules/shared/helpers/envHelper.ts b/packages/server/modules/shared/helpers/envHelper.ts index 9d398f0d9..7e3093ba7 100644 --- a/packages/server/modules/shared/helpers/envHelper.ts +++ b/packages/server/modules/shared/helpers/envHelper.ts @@ -112,6 +112,10 @@ export function getRedisUrl() { return getStringFromEnv('REDIS_URL') } +export const previewServiceShouldUsePrivateObjectsServerUrl = (): boolean => { + return getBooleanFromEnv('PREVIEW_SERVICE_USE_PRIVATE_OBJECTS_SERVER_URL') +} + export const getPreviewServiceRedisUrl = (): string | undefined => { return process.env['PREVIEW_SERVICE_REDIS_URL'] } @@ -221,20 +225,19 @@ export function getFrontendOrigin() { } /** - * Get server app origin/base URL + * Get server app origin/base URL. + * This is the public server URL, i.e. 'canonical url', used for external communication. */ export function getServerOrigin() { return mustGetUrlFromEnv('CANONICAL_URL', true).origin } -export function getPrivateServerOrigin() { - try { - const url = getUrlFromEnv('PRIVATE_SERVER_URL', true) - if (!url) return url - return url.origin - } catch { - return null - } +/** + * + * @returns the private server origin, which is used for internal communication between services + */ +export function getPrivateObjectsServerOrigin() { + return mustGetUrlFromEnv('PRIVATE_OBJECTS_SERVER_URL', true).origin } export function getBindAddress(aDefault: string = '127.0.0.1') { diff --git a/utils/helm/speckle-server/templates/_helpers.tpl b/utils/helm/speckle-server/templates/_helpers.tpl index 1e733bbed..748779d6d 100644 --- a/utils/helm/speckle-server/templates/_helpers.tpl +++ b/utils/helm/speckle-server/templates/_helpers.tpl @@ -528,7 +528,6 @@ Retrieve the s3 parameters from ConfigMap if enabled, or default to retrieving t {{- end }} {{- end }} - {{/* Generate the environment variables for Speckle server and Speckle objects deployments */}} @@ -542,6 +541,10 @@ Generate the environment variables for Speckle server and Speckle objects deploy - name: PORT value: {{ include "server.port" $ | quote }} + +- name: PRIVATE_OBJECTS_SERVER_URL + value: {{ printf "http://%s:%s" ( include "objects.service.fqdn" $ ) ( include "objects.port" $ ) }} + - name: LOG_LEVEL value: {{ .Values.server.logLevel }} - name: LOG_PRETTY @@ -799,6 +802,12 @@ Generate the environment variables for Speckle server and Speckle objects deploy value: {{ .Values.server.gendoAI.ratelimiting.burstRenderRequestPeriodSeconds | quote }} {{- end }} +# *** Preview service *** +{{- if .Values.preview_service.deployInCluster }} +- name: PREVIEW_SERVICE_USE_PRIVATE_OBJECTS_SERVER_URL + value: "true" +{{- end }} + # *** Redis *** - name: REDIS_URL valueFrom: diff --git a/utils/helm/speckle-server/templates/preview_service/deployment.yml b/utils/helm/speckle-server/templates/preview_service/deployment.yml index 01bba8ef6..7ac6f8041 100644 --- a/utils/helm/speckle-server/templates/preview_service/deployment.yml +++ b/utils/helm/speckle-server/templates/preview_service/deployment.yml @@ -1,3 +1,4 @@ +{{- if .Values.preview_service.deployInCluster }} apiVersion: apps/v1 kind: Deployment metadata: @@ -121,4 +122,4 @@ spec: # Should be > preview generation time ( 1 hour for good measure ) terminationGracePeriodSeconds: 3600 - +{{- end }} diff --git a/utils/helm/speckle-server/templates/preview_service/networkpolicy.cilium.yml b/utils/helm/speckle-server/templates/preview_service/networkpolicy.cilium.yml index 828509cb4..5b4e799c0 100644 --- a/utils/helm/speckle-server/templates/preview_service/networkpolicy.cilium.yml +++ b/utils/helm/speckle-server/templates/preview_service/networkpolicy.cilium.yml @@ -1,3 +1,4 @@ +{{- if .Values.preview_service.deployInCluster }} {{- if (and (.Values.preview_service.networkPolicy.enabled) (eq .Values.networkPlugin.type "cilium")) -}} apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy @@ -38,3 +39,4 @@ spec: # postgres {{ include "speckle.networkpolicy.egress.postgres.cilium" $ | indent 4 }} {{- end }} +{{- end }} diff --git a/utils/helm/speckle-server/templates/preview_service/networkpolicy.kubernetes.yml b/utils/helm/speckle-server/templates/preview_service/networkpolicy.kubernetes.yml index b4c386b11..d5dbff0ab 100644 --- a/utils/helm/speckle-server/templates/preview_service/networkpolicy.kubernetes.yml +++ b/utils/helm/speckle-server/templates/preview_service/networkpolicy.kubernetes.yml @@ -1,3 +1,4 @@ +{{- if .Values.preview_service.deployInCluster }} {{- if (and (.Values.preview_service.networkPolicy.enabled) (eq .Values.networkPlugin.type "kubernetes")) -}} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -38,4 +39,5 @@ spec: protocol: UDP # postgres {{ include "speckle.networkpolicy.egress.postgres" $ | indent 4 }} -{{- end -}} +{{- end }} +{{- end }} diff --git a/utils/helm/speckle-server/templates/preview_service/service.yml b/utils/helm/speckle-server/templates/preview_service/service.yml index b0b186306..e2156a71c 100644 --- a/utils/helm/speckle-server/templates/preview_service/service.yml +++ b/utils/helm/speckle-server/templates/preview_service/service.yml @@ -1,3 +1,4 @@ +{{- if .Values.preview_service.deployInCluster }} apiVersion: v1 kind: Service metadata: @@ -14,3 +15,4 @@ spec: name: web port: {{ .Values.preview_service.port }} targetPort: metrics +{{- end }} diff --git a/utils/helm/speckle-server/templates/preview_service/serviceaccount.yml b/utils/helm/speckle-server/templates/preview_service/serviceaccount.yml index 279e661e2..e078289ed 100644 --- a/utils/helm/speckle-server/templates/preview_service/serviceaccount.yml +++ b/utils/helm/speckle-server/templates/preview_service/serviceaccount.yml @@ -1,3 +1,4 @@ +{{- if .Values.preview_service.deployInCluster }} {{- if .Values.preview_service.serviceAccount.create -}} apiVersion: v1 kind: ServiceAccount @@ -21,3 +22,4 @@ secrets: - name: {{ default .Values.secretName .Values.redis.previewServiceConnectionString.secretName }} {{- end }} {{- end -}} +{{- end }} diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 09b6e39ea..25d17d47e 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -1884,6 +1884,11 @@ "preview_service": { "type": "object", "properties": { + "deployInCluster": { + "type": "boolean", + "description": "If enabled, the Preview Service will be deployed within the cluster and speckle-server will be configured to send the kubernetes service url of the objects server to the Preview Service.", + "default": true + }, "dedicatedPreviewsQueue": { "type": "boolean", "description": "Allows using a dedicated redis url for the preview service job queue", diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index 3b7476913..de2fb8246 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -1101,6 +1101,8 @@ frontend_2: ## @descriptionEnd ## preview_service: + ## @param preview_service.deployInCluster If enabled, the Preview Service will be deployed within the cluster and speckle-server will be configured to send the kubernetes service url of the objects server to the Preview Service. + deployInCluster: true ## @param preview_service.dedicatedPreviewsQueue Allows using a dedicated redis url for the preview service job queue ## dedicatedPreviewsQueue: false From 162ac92c2d70e3939c5d45e85e30ec0e911f2c71 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 17 Mar 2025 16:29:20 +0100 Subject: [PATCH 04/11] Fix: Minor connectors page copy changes (#4210) --- packages/frontend-2/lib/dashboard/helpers/connectors.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend-2/lib/dashboard/helpers/connectors.ts b/packages/frontend-2/lib/dashboard/helpers/connectors.ts index 6953bda87..f7a68de04 100644 --- a/packages/frontend-2/lib/dashboard/helpers/connectors.ts +++ b/packages/frontend-2/lib/dashboard/helpers/connectors.ts @@ -18,7 +18,7 @@ export const connectorItems: ConnectorItem[] = [ title: 'Revit', slug: 'revit', description: - 'Publish and load models to boost design coordination and business intelligence workflows.', + 'Publish and load Revit models to boost design coordination and business intelligence workflows.', url: 'https://www.speckle.systems/connectors/revit', image: '/images/connectors/revit.png', categories: [ConnectorCategory.NextGen, ConnectorCategory.BIM] @@ -36,7 +36,7 @@ export const connectorItems: ConnectorItem[] = [ title: 'Power BI', slug: 'powerbi', description: - 'Load Power BI models to boost design coordination and business intelligence workflows.', + 'Load your models into Power BI to boost design coordination and business intelligence workflows.', url: 'https://www.speckle.systems/connectors/power-bi', image: '/images/connectors/powerbi.png', categories: [ConnectorCategory.BusinessIntelligence] @@ -139,7 +139,7 @@ export const connectorItems: ConnectorItem[] = [ { title: 'Blender', slug: 'blender', - description: 'Load Blender models to boost design coordination workflows.', + description: 'Load models into Blender to boost design coordination workflows.', image: '/images/connectors/blender.png', categories: [ConnectorCategory.Visualisation, ConnectorCategory.CADAndModeling], isComingSoon: true From 159e7858ffea91c087c237682ccd9bd62b659af2 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 17 Mar 2025 16:58:28 +0100 Subject: [PATCH 05/11] Feat: Various WorkspaceSwitcher improvements (#4209) --- .../components/dashboard/sidebar/New.vue | 8 ++ .../frontend-2/components/header/NavBar.vue | 4 +- .../WorkspaceSwitcher/Item.vue} | 4 +- .../WorkspaceSwitcher.vue | 97 ++++++++++++------- .../components/project/model-page/Header.vue | 5 +- .../components/project/page/Header.vue | 17 +--- .../components/viewer/PreSetupWrapper.vue | 12 +-- .../lib/common/generated/gql/gql.ts | 36 +++++-- .../lib/common/generated/gql/graphql.ts | 26 +++-- .../lib/navigation/composables/navigation.ts | 56 ++++++++--- .../lib/navigation/graphql/queries.ts | 15 ++- .../lib/user/composables/workspaces.ts | 24 ----- 12 files changed, 186 insertions(+), 118 deletions(-) rename packages/frontend-2/components/{dashboard/sidebar/WorkspaceItem.vue => header/WorkspaceSwitcher/Item.vue} (87%) rename packages/frontend-2/components/header/{ => WorkspaceSwitcher}/WorkspaceSwitcher.vue (76%) delete mode 100644 packages/frontend-2/lib/user/composables/workspaces.ts diff --git a/packages/frontend-2/components/dashboard/sidebar/New.vue b/packages/frontend-2/components/dashboard/sidebar/New.vue index 24a12777c..eeaeec399 100644 --- a/packages/frontend-2/components/dashboard/sidebar/New.vue +++ b/packages/frontend-2/components/dashboard/sidebar/New.vue @@ -30,6 +30,10 @@ class="border-r border-outline-3 px-2 pt-3 pb-2 bg-foundation-page" > + + + +