From 8197bb74a373f343ef585b3e91ecf58f63a37d44 Mon Sep 17 00:00:00 2001
From: Iain Sproat <68657+iainsproat@users.noreply.github.com>
Date: Thu, 12 Dec 2024 10:03:25 +0000
Subject: [PATCH 01/15] feat(multi-region): metrics for knex for all regional
databases (#3580)
* feat(multi-region): metrics for knex for all regional databases
* improve typing in knex monitoring
* error logging around migrations
* await async calls for db connections
- add 'region' label
* add missing 'await' statements
* more missing 'await'
* guard against re-adding listeners
* It was possible for update to be called before initialize
- this change collapses both into initialize, and adds checks to ensure initialization is done before being updated for new regions
* separate back into non-exported const and rename
* align with main
* Amend order at which metrics is enabled
---
packages/server/app.ts | 5 +-
.../highfrequencyMonitoring.ts | 4 +-
.../knexConnectionPool.ts | 32 +-
packages/server/logging/index.ts | 10 +-
packages/server/logging/knexMonitoring.ts | 331 +++++++++++-------
5 files changed, 239 insertions(+), 143 deletions(-)
diff --git a/packages/server/app.ts b/packages/server/app.ts
index eb398e768..c6d69f130 100644
--- a/packages/server/app.ts
+++ b/packages/server/app.ts
@@ -399,12 +399,13 @@ export async function init() {
const app = express()
app.disable('x-powered-by')
- Logging(app)
-
// Moves things along automatically on restart.
// Should perhaps be done manually?
await migrateDbToLatest({ region: 'main', db: knex })
+ // Logging relies on 'regions' table in the database, so much be initialized after migrations
+ await Logging(app)
+
app.use(cookieParser())
app.use(DetermineRequestIdMiddleware)
app.use(determineClientIpAddressMiddleware)
diff --git a/packages/server/logging/highFrequencyMetrics/highfrequencyMonitoring.ts b/packages/server/logging/highFrequencyMetrics/highfrequencyMonitoring.ts
index a38c80bb5..b11bfe6cd 100644
--- a/packages/server/logging/highFrequencyMetrics/highfrequencyMonitoring.ts
+++ b/packages/server/logging/highFrequencyMetrics/highfrequencyMonitoring.ts
@@ -14,7 +14,9 @@ type MetricConfig = {
prefix?: string
labels?: Record
buckets?: Record
- knex: Knex
+ getDbClients: () => Promise<
+ Array<{ client: Knex; isMain: boolean; regionKey: string }>
+ >
}
type HighFrequencyMonitor = {
diff --git a/packages/server/logging/highFrequencyMetrics/knexConnectionPool.ts b/packages/server/logging/highFrequencyMetrics/knexConnectionPool.ts
index 72cf4b89c..6a6afc5fd 100644
--- a/packages/server/logging/highFrequencyMetrics/knexConnectionPool.ts
+++ b/packages/server/logging/highFrequencyMetrics/knexConnectionPool.ts
@@ -31,16 +31,17 @@ type MetricConfig = {
prefix?: string
labels?: Record
buckets?: Record
- knex: Knex
+ getDbClients: () => Promise<
+ Array<{ client: Knex; isMain: boolean; regionKey: string }>
+ >
}
export const knexConnections = (registry: Registry, config: MetricConfig): Metric => {
const registers = registry ? [registry] : undefined
const namePrefix = config.prefix ?? ''
const labels = config.labels ?? {}
- const labelNames = Object.keys(labels)
+ const labelNames = [...Object.keys(labels), 'region']
const buckets = { ...DEFAULT_KNEX_TOTAL_BUCKETS, ...config.buckets }
- const knex = config.knex
const knexConnectionsFree = new Histogram({
name: namePrefix + KNEX_CONNECTIONS_FREE,
@@ -91,15 +92,24 @@ export const knexConnections = (registry: Registry, config: MetricConfig): Metri
})
return {
- collect: () => {
- const connPool = knex.client.pool
+ collect: async () => {
+ for (const dbClient of await config.getDbClients()) {
+ const labelsAndRegion = { ...labels, region: dbClient.regionKey }
+ const connPool = dbClient.client.client.pool
- knexConnectionsFree.observe(labels, connPool.numFree())
- knexConnectionsUsed.observe(labels, connPool.numUsed())
- knexPendingAcquires.observe(labels, connPool.numPendingAcquires())
- knexPendingCreates.observe(labels, connPool.numPendingCreates())
- knexPendingValidations.observe(labels, connPool.numPendingValidations())
- knexRemainingCapacity.observe(labels, numberOfFreeConnections(knex))
+ knexConnectionsFree.observe(labelsAndRegion, connPool.numFree())
+ knexConnectionsUsed.observe(labelsAndRegion, connPool.numUsed())
+ knexPendingAcquires.observe(labelsAndRegion, connPool.numPendingAcquires())
+ knexPendingCreates.observe(labelsAndRegion, connPool.numPendingCreates())
+ knexPendingValidations.observe(
+ labelsAndRegion,
+ connPool.numPendingValidations()
+ )
+ knexRemainingCapacity.observe(
+ labelsAndRegion,
+ numberOfFreeConnections(dbClient.client)
+ )
+ }
}
}
}
diff --git a/packages/server/logging/index.ts b/packages/server/logging/index.ts
index 6489ae634..c1020813e 100644
--- a/packages/server/logging/index.ts
+++ b/packages/server/logging/index.ts
@@ -4,14 +4,14 @@ import promBundle from 'express-prom-bundle'
import { initKnexPrometheusMetrics } from '@/logging/knexMonitoring'
import { initHighFrequencyMonitoring } from '@/logging/highFrequencyMetrics/highfrequencyMonitoring'
-import knex from '@/db/knex'
import { highFrequencyMetricsCollectionPeriodMs } from '@/modules/shared/helpers/envHelper'
import { startupLogger as logger } from '@/logging/logging'
import type express from 'express'
+import { getAllRegisteredDbClients } from '@/modules/multiregion/utils/dbSelector'
let prometheusInitialized = false
-export default function (app: express.Express) {
+export default async function (app: express.Express) {
if (!prometheusInitialized) {
prometheusInitialized = true
prometheusClient.register.clear()
@@ -24,14 +24,14 @@ export default function (app: express.Express) {
register: prometheusClient.register,
collectionPeriodMilliseconds: highFrequencyMetricsCollectionPeriodMs(),
config: {
- knex
+ getDbClients: getAllRegisteredDbClients
}
})
highfrequencyMonitoring.start()
- initKnexPrometheusMetrics({
+ await initKnexPrometheusMetrics({
register: prometheusClient.register,
- db: knex,
+ getAllDbClients: getAllRegisteredDbClients,
logger
})
const expressMetricsMiddleware = promBundle({
diff --git a/packages/server/logging/knexMonitoring.ts b/packages/server/logging/knexMonitoring.ts
index 5d327ca42..f2d087b90 100644
--- a/packages/server/logging/knexMonitoring.ts
+++ b/packages/server/logging/knexMonitoring.ts
@@ -5,150 +5,228 @@ import { Logger } from 'pino'
import { toNDecimalPlaces } from '@/modules/core/utils/formatting'
import { omit } from 'lodash'
-export const initKnexPrometheusMetrics = (params: {
- db: Knex
+let metricQueryDuration: prometheusClient.Summary
+let metricQueryErrors: prometheusClient.Counter
+let metricConnectionAcquisitionDuration: prometheusClient.Histogram
+let metricConnectionPoolErrors: prometheusClient.Counter
+let metricConnectionInUseDuration: prometheusClient.Histogram
+let metricConnectionPoolReapingDuration: prometheusClient.Histogram
+const initializedRegions: string[] = []
+let initializedPollingMetrics = false
+
+export const initKnexPrometheusMetrics = async (params: {
+ getAllDbClients: () => Promise<
+ Array<{ client: Knex; isMain: boolean; regionKey: string }>
+ >
register: Registry
logger: Logger
}) => {
- const normalizeSqlMethod = (sqlMethod: string) => {
- if (!sqlMethod) return 'unknown'
- switch (sqlMethod.toLocaleLowerCase()) {
- case 'first':
- return 'select'
- default:
- return sqlMethod.toLocaleLowerCase()
- }
+ if (!initializedPollingMetrics) {
+ initializedPollingMetrics = true
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_free',
+ labelNames: ['region'],
+ help: 'Number of free DB connections',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ dbClient.client.client.pool.numFree()
+ )
+ }
+ }
+ })
+
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_used',
+ labelNames: ['region'],
+ help: 'Number of used DB connections',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ dbClient.client.client.pool.numUsed()
+ )
+ }
+ }
+ })
+
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_pending',
+ labelNames: ['region'],
+ help: 'Number of pending DB connection aquires',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ dbClient.client.client.pool.numPendingAcquires()
+ )
+ }
+ }
+ })
+
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_pending_creates',
+ labelNames: ['region'],
+ help: 'Number of pending DB connection creates',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ dbClient.client.client.pool.numPendingCreates()
+ )
+ }
+ }
+ })
+
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_pending_validations',
+ labelNames: ['region'],
+ help: 'Number of pending DB connection validations. This is a state between pending acquisition and acquiring a connection.',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ dbClient.client.client.pool.numPendingValidations()
+ )
+ }
+ }
+ })
+
+ new prometheusClient.Gauge({
+ registers: [params.register],
+ name: 'speckle_server_knex_remaining_capacity',
+ labelNames: ['region'],
+ help: 'Remaining capacity of the DB connection pool',
+ async collect() {
+ for (const dbClient of await params.getAllDbClients()) {
+ this.set(
+ { region: dbClient.regionKey },
+ numberOfFreeConnections(dbClient.client)
+ )
+ }
+ }
+ })
+
+ metricQueryDuration = new prometheusClient.Summary({
+ registers: [params.register],
+ labelNames: ['sqlMethod', 'sqlNumberBindings', 'region'],
+ name: 'speckle_server_knex_query_duration',
+ help: 'Summary of the DB query durations in seconds'
+ })
+
+ metricQueryErrors = new prometheusClient.Counter({
+ registers: [params.register],
+ labelNames: ['sqlMethod', 'sqlNumberBindings', 'region'],
+ name: 'speckle_server_knex_query_errors',
+ help: 'Number of DB queries with errors'
+ })
+
+ metricConnectionAcquisitionDuration = new prometheusClient.Histogram({
+ registers: [params.register],
+ name: 'speckle_server_knex_connection_acquisition_duration',
+ labelNames: ['region'],
+ help: 'Summary of the DB connection acquisition duration, from request to acquire connection from pool until successfully acquired, in seconds'
+ })
+
+ metricConnectionPoolErrors = new prometheusClient.Counter({
+ registers: [params.register],
+ name: 'speckle_server_knex_connection_acquisition_errors',
+ labelNames: ['region'],
+ help: 'Number of DB connection pool acquisition errors'
+ })
+
+ metricConnectionInUseDuration = new prometheusClient.Histogram({
+ registers: [params.register],
+ name: 'speckle_server_knex_connection_usage_duration',
+ labelNames: ['region'],
+ help: 'Summary of the DB connection duration, from successful acquisition of connection from pool until release back to pool, in seconds'
+ })
+
+ metricConnectionPoolReapingDuration = new prometheusClient.Histogram({
+ registers: [params.register],
+ name: 'speckle_server_knex_connection_pool_reaping_duration',
+ labelNames: ['region'],
+ help: 'Summary of the DB connection pool reaping duration, in seconds. Reaping is the process of removing idle connections from the pool.'
+ })
}
+ // configure hooks on knex
+ for (const dbClient of await params.getAllDbClients()) {
+ if (initializedRegions.includes(dbClient.regionKey)) continue
+ initKnexPrometheusMetricsForRegionEvents({
+ logger: params.logger,
+ region: dbClient.regionKey,
+ db: dbClient.client
+ })
+ initializedRegions.push(dbClient.regionKey)
+ }
+}
+
+const normalizeSqlMethod = (sqlMethod: string) => {
+ if (!sqlMethod) return 'unknown'
+ switch (sqlMethod.toLocaleLowerCase()) {
+ case 'first':
+ return 'select'
+ default:
+ return sqlMethod.toLocaleLowerCase()
+ }
+}
+
+interface QueryEvent extends Knex.Sql {
+ __knexUid: string
+ __knexTxId: string
+ __knexQueryUid: string
+}
+
+const initKnexPrometheusMetricsForRegionEvents = async (params: {
+ region: string
+ db: Knex
+ logger: Logger
+}) => {
+ const { region, db } = params
const queryStartTime: Record = {}
const connectionAcquisitionStartTime: Record = {}
const connectionInUseStartTime: Record = {}
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_free',
- help: 'Number of free DB connections',
- collect() {
- this.set(params.db.client.pool.numFree())
- }
- })
-
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_used',
- help: 'Number of used DB connections',
- collect() {
- this.set(params.db.client.pool.numUsed())
- }
- })
-
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_pending',
- help: 'Number of pending DB connection aquires',
- collect() {
- this.set(params.db.client.pool.numPendingAcquires())
- }
- })
-
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_pending_creates',
- help: 'Number of pending DB connection creates',
- collect() {
- this.set(params.db.client.pool.numPendingCreates())
- }
- })
-
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_pending_validations',
- help: 'Number of pending DB connection validations. This is a state between pending acquisition and acquiring a connection.',
- collect() {
- this.set(params.db.client.pool.numPendingValidations())
- }
- })
-
- new prometheusClient.Gauge({
- registers: [params.register],
- name: 'speckle_server_knex_remaining_capacity',
- help: 'Remaining capacity of the DB connection pool',
- collect() {
- this.set(numberOfFreeConnections(params.db))
- }
- })
-
- const metricQueryDuration = new prometheusClient.Summary({
- registers: [params.register],
- labelNames: ['sqlMethod', 'sqlNumberBindings'],
- name: 'speckle_server_knex_query_duration',
- help: 'Summary of the DB query durations in seconds'
- })
-
- const metricQueryErrors = new prometheusClient.Counter({
- registers: [params.register],
- labelNames: ['sqlMethod', 'sqlNumberBindings'],
- name: 'speckle_server_knex_query_errors',
- help: 'Number of DB queries with errors'
- })
-
- const metricConnectionAcquisitionDuration = new prometheusClient.Histogram({
- registers: [params.register],
- name: 'speckle_server_knex_connection_acquisition_duration',
- help: 'Summary of the DB connection acquisition duration, from request to acquire connection from pool until successfully acquired, in seconds'
- })
-
- const metricConnectionPoolErrors = new prometheusClient.Counter({
- registers: [params.register],
- name: 'speckle_server_knex_connection_acquisition_errors',
- help: 'Number of DB connection pool acquisition errors'
- })
-
- const metricConnectionInUseDuration = new prometheusClient.Histogram({
- registers: [params.register],
- name: 'speckle_server_knex_connection_usage_duration',
- help: 'Summary of the DB connection duration, from successful acquisition of connection from pool until release back to pool, in seconds'
- })
-
- const metricConnectionPoolReapingDuration = new prometheusClient.Histogram({
- registers: [params.register],
- name: 'speckle_server_knex_connection_pool_reaping_duration',
- help: 'Summary of the DB connection pool reaping duration, in seconds. Reaping is the process of removing idle connections from the pool.'
- })
-
- // configure hooks on knex
-
- params.db.on('query', (data) => {
+ db.on('query', (data: QueryEvent) => {
const queryId = data.__knexQueryUid + ''
queryStartTime[queryId] = performance.now()
})
- params.db.on('query-response', (_data, querySpec) => {
- const queryId = querySpec.__knexQueryUid + ''
+ db.on('query-response', (_response: unknown, data: QueryEvent) => {
+ const queryId = data.__knexQueryUid + ''
const durationMs = performance.now() - queryStartTime[queryId]
const durationSec = toNDecimalPlaces(durationMs / 1000, 2)
delete queryStartTime[queryId]
if (!isNaN(durationSec))
metricQueryDuration
.labels({
- sqlMethod: normalizeSqlMethod(querySpec.method),
- sqlNumberBindings: querySpec.bindings?.length || -1
+ region,
+ sqlMethod: normalizeSqlMethod(data.method),
+ sqlNumberBindings: data.bindings?.length || -1
})
.observe(durationSec)
params.logger.debug(
{
- sql: querySpec.sql,
- sqlMethod: normalizeSqlMethod(querySpec.method),
+ region,
+ sql: data.sql,
+ sqlMethod: normalizeSqlMethod(data.method),
sqlQueryId: queryId,
sqlQueryDurationMs: toNDecimalPlaces(durationMs, 0),
- sqlNumberBindings: querySpec.bindings?.length || -1
+ sqlNumberBindings: data.bindings?.length || -1
},
"DB query successfully completed, for method '{sqlMethod}', after {sqlQueryDurationMs}ms"
)
})
- params.db.on('query-error', (err, querySpec) => {
- const queryId = querySpec.__knexQueryUid + ''
+ db.on('query-error', (err: unknown, data: QueryEvent) => {
+ const queryId = data.__knexQueryUid + ''
const durationMs = performance.now() - queryStartTime[queryId]
const durationSec = toNDecimalPlaces(durationMs / 1000, 2)
delete queryStartTime[queryId]
@@ -156,25 +234,27 @@ export const initKnexPrometheusMetrics = (params: {
if (!isNaN(durationSec))
metricQueryDuration
.labels({
- sqlMethod: normalizeSqlMethod(querySpec.method),
- sqlNumberBindings: querySpec.bindings?.length || -1
+ region,
+ sqlMethod: normalizeSqlMethod(data.method),
+ sqlNumberBindings: data.bindings?.length || -1
})
.observe(durationSec)
metricQueryErrors.inc()
params.logger.warn(
{
- err: omit(err, 'detail'),
- sql: querySpec.sql,
- sqlMethod: normalizeSqlMethod(querySpec.method),
+ err: typeof err === 'object' ? omit(err, 'detail') : err,
+ region,
+ sql: data.sql,
+ sqlMethod: normalizeSqlMethod(data.method),
sqlQueryId: queryId,
sqlQueryDurationMs: toNDecimalPlaces(durationMs, 0),
- sqlNumberBindings: querySpec.bindings?.length || -1
+ sqlNumberBindings: data.bindings?.length || -1
},
'DB query errored for {sqlMethod} after {sqlQueryDurationMs}ms'
)
})
- const pool = params.db.client.pool
+ const pool = db.client.pool
// configure hooks on knex connection pool
pool.on('acquireRequest', (eventId: number) => {
@@ -190,7 +270,8 @@ export const initKnexPrometheusMetrics = (params: {
const now = performance.now()
const durationMs = now - connectionAcquisitionStartTime[eventId]
delete connectionAcquisitionStartTime[eventId]
- if (!isNaN(durationMs)) metricConnectionAcquisitionDuration.observe(durationMs)
+ if (!isNaN(durationMs))
+ metricConnectionAcquisitionDuration.labels({ region }).observe(durationMs)
// successful acquisition is the start of usage, so record that start time
let knexUid: string | undefined = undefined
@@ -234,7 +315,8 @@ export const initKnexPrometheusMetrics = (params: {
const now = performance.now()
const durationMs = now - connectionInUseStartTime[knexUid]
- if (!isNaN(durationMs)) metricConnectionInUseDuration.observe(durationMs)
+ if (!isNaN(durationMs))
+ metricConnectionInUseDuration.labels({ region }).observe(durationMs)
// params.logger.debug(
// {
// knexUid,
@@ -263,7 +345,8 @@ export const initKnexPrometheusMetrics = (params: {
pool.on('stopReaping', () => {
if (!reapingStartTime) return
const durationMs = performance.now() - reapingStartTime
- if (!isNaN(durationMs)) metricConnectionPoolReapingDuration.observe(durationMs)
+ if (!isNaN(durationMs))
+ metricConnectionPoolReapingDuration.labels({ region }).observe(durationMs)
reapingStartTime = undefined
})
From c6301f8fc2ab865f5d37859a754aee2763050c93 Mon Sep 17 00:00:00 2001
From: Mike
Date: Thu, 12 Dec 2024 13:10:28 +0100
Subject: [PATCH 02/15] Fix: Hide seat counts and pricing for academia and
unlimited plans (#3682)
---
.../settings/workspaces/Billing.vue | 60 +++++++++++--------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/packages/frontend-2/components/settings/workspaces/Billing.vue b/packages/frontend-2/components/settings/workspaces/Billing.vue
index 73074c6b6..dbd2838ac 100644
--- a/packages/frontend-2/components/settings/workspaces/Billing.vue
+++ b/packages/frontend-2/components/settings/workspaces/Billing.vue
@@ -49,30 +49,38 @@
-
- {{
- statusIsTrial
- ? 'Expected bill'
- : subscription?.billingInterval === BillingInterval.Yearly
- ? 'Annual bill'
- : 'Monthly bill'
- }}
-
-
- {{ billValue }} per
- {{
- subscription?.billingInterval === BillingInterval.Yearly
- ? 'year'
- : 'month'
- }}
-
-
- {{ billDescription }}
-
-
+
+
+ {{
+ statusIsTrial
+ ? 'Expected bill'
+ : subscription?.billingInterval === BillingInterval.Yearly
+ ? 'Annual bill'
+ : 'Monthly bill'
+ }}
+
+
+ {{ billValue }} per
+ {{
+ subscription?.billingInterval === BillingInterval.Yearly
+ ? 'year'
+ : 'month'
+ }}
+
+
+ {{ billDescription }}
+
+
+
+
+ Expected bill
+
+ {{ isAcademiaPlan ? 'Free' : 'Not applicable' }}
+
+
@@ -123,6 +131,7 @@
class="pt-4"
/>
currentPlan.value?.name === WorkspacePlans.Academia
+)
const isPurchasablePlan = computed(() => isPaidPlan(currentPlan.value?.name))
const seatPrice = computed(() =>
currentPlan.value && subscription.value
From 9e0e6a9c0d8b1b200897cc2347312af58e33588d Mon Sep 17 00:00:00 2001
From: Alexandru Popovici
Date: Thu, 12 Dec 2024 14:37:39 +0200
Subject: [PATCH 03/15] SpeckleInstancedMeshes now recrete their shadow depth
material whenever the instance configuration changes (#3681)
---
.../src/Extensions/ExtendedSelection.ts | 2 +-
packages/viewer-sandbox/src/main.ts | 7 +++++--
.../shaders/speckle-standard-colored-vert.ts | 4 ++++
.../src/modules/objects/SpeckleInstancedMesh.ts | 11 +++++++++++
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/packages/viewer-sandbox/src/Extensions/ExtendedSelection.ts b/packages/viewer-sandbox/src/Extensions/ExtendedSelection.ts
index 4e2fdbcbc..a7966d342 100644
--- a/packages/viewer-sandbox/src/Extensions/ExtendedSelection.ts
+++ b/packages/viewer-sandbox/src/Extensions/ExtendedSelection.ts
@@ -138,6 +138,6 @@ export class ExtendedSelection extends SelectionExtension {
)
}
this.lastGizmoTranslation.copy(this.dummyAnchor.position)
- this.viewer.requestRender(UpdateFlags.RENDER | UpdateFlags.SHADOWS)
+ this.viewer.requestRender(UpdateFlags.RENDER_RESET | UpdateFlags.SHADOWS)
}
}
diff --git a/packages/viewer-sandbox/src/main.ts b/packages/viewer-sandbox/src/main.ts
index a473e0716..afe349945 100644
--- a/packages/viewer-sandbox/src/main.ts
+++ b/packages/viewer-sandbox/src/main.ts
@@ -21,6 +21,7 @@ import { SectionTool } from '@speckle/viewer'
import { SectionOutlines } from '@speckle/viewer'
import { ViewModesKeys } from './Extensions/ViewModesKeys'
import { BoxSelection } from './Extensions/BoxSelection'
+import { ExtendedSelection } from './Extensions/ExtendedSelection'
const createViewer = async (containerName: string, stream: string) => {
const container = document.querySelector(containerName)
@@ -45,7 +46,8 @@ const createViewer = async (containerName: string, stream: string) => {
await viewer.init()
const cameraController = viewer.createExtension(CameraController)
- const selection = viewer.createExtension(SelectionExtension)
+ const selection = viewer.createExtension(ExtendedSelection)
+ selection.init()
const sections = viewer.createExtension(SectionTool)
viewer.createExtension(SectionOutlines)
const measurements = viewer.createExtension(MeasurementsExtension)
@@ -115,7 +117,7 @@ const getStream = () => {
// 'https://app.speckle.systems/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.systems/streams/58b5648c4d/commits/60371ecb2d'
// 'Super' heavy revit shit
- 'https://app.speckle.systems/streams/e6f9156405/commits/0694d53bb5'
+ // 'https://app.speckle.systems/streams/e6f9156405/commits/0694d53bb5'
// IFC building (good for a tree based structure)
// 'https://latest.speckle.systems/streams/92b620fb17/commits/2ebd336223'
// IFC story, a subtree of the above
@@ -454,6 +456,7 @@ const getStream = () => {
// 'https://app.speckle.systems/projects/344f803f81/models/5582ab673e'
// 'https://speckle.xyz/streams/27e89d0ad6/commits/5ed4b74252'
+ 'https://app.speckle.systems/projects/e89b61b65c/models/2a0995f124'
)
}
diff --git a/packages/viewer/src/modules/materials/shaders/speckle-standard-colored-vert.ts b/packages/viewer/src/modules/materials/shaders/speckle-standard-colored-vert.ts
index e48e38e97..c08fd8630 100644
--- a/packages/viewer/src/modules/materials/shaders/speckle-standard-colored-vert.ts
+++ b/packages/viewer/src/modules/materials/shaders/speckle-standard-colored-vert.ts
@@ -226,6 +226,10 @@ void main() {
vec4 rtePivotShadow = computeRelativePositionSeparate(tPivotLow.xyz, tPivotHigh.xyz, uShadowViewer_low, uShadowViewer_high);
shadowPosition.xyz = rotate_vertex_position((shadowPosition - rtePivotShadow).xyz, tQuaternion) * tScale.xyz + rtePivotShadow.xyz + tTranslation.xyz;
#endif
+ #ifdef USE_INSTANCING
+ vec4 rtePivotShadow = computeRelativePositionSeparate(ZERO3, ZERO3, uShadowViewer_low, uShadowViewer_high);
+ shadowPosition.xyz = (mat3(instanceMatrix) * (shadowPosition - rtePivotShadow).xyz) + rtePivotShadow.xyz + instanceMatrix[3].xyz;
+ #endif
shadowWorldPosition = modelMatrix * shadowPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );
vDirectionalShadowCoord[ i ] = shadowMatrix * shadowWorldPosition;
diff --git a/packages/viewer/src/modules/objects/SpeckleInstancedMesh.ts b/packages/viewer/src/modules/objects/SpeckleInstancedMesh.ts
index d890f67d7..8c03f99f1 100644
--- a/packages/viewer/src/modules/objects/SpeckleInstancedMesh.ts
+++ b/packages/viewer/src/modules/objects/SpeckleInstancedMesh.ts
@@ -11,6 +11,7 @@ import {
Object3D,
Ray,
Raycaster,
+ RGBADepthPacking,
SkinnedMesh,
Sphere,
Triangle,
@@ -29,6 +30,7 @@ import {
} from '../batching/Batch.js'
import { SpeckleRaycaster } from './SpeckleRaycaster.js'
import Logger from '../utils/Logger.js'
+import SpeckleDepthMaterial from '../materials/SpeckleDepthMaterial.js'
const _inverseMatrix = new Matrix4()
const _ray = new Ray()
@@ -183,6 +185,7 @@ export default class SpeckleInstancedMesh extends Group {
public updateDrawGroups(transformBuffer: Float32Array, gradientBuffer: Float32Array) {
this.instances.forEach((value: InstancedMesh) => {
this.remove(value)
+ value.customDepthMaterial?.dispose()
value.dispose()
})
this.instances.length = 0
@@ -218,6 +221,14 @@ export default class SpeckleInstancedMesh extends Group {
group.instanceMatrix.needsUpdate = true
group.layers.set(ObjectLayers.STREAM_CONTENT_MESH)
group.frustumCulled = false
+ group.customDepthMaterial = new SpeckleDepthMaterial(
+ {
+ depthPacking: RGBADepthPacking
+ },
+ ['USE_RTE', 'ALPHATEST_REJECTION']
+ )
+ group.castShadow = !material.transparent
+ group.receiveShadow = !material.transparent
this.instances.push(group)
this.add(group)
From 60ff23d73d8d09c05df2689c8a096decc53a79a3 Mon Sep 17 00:00:00 2001
From: Alexandru Popovici
Date: Thu, 12 Dec 2024 15:42:10 +0200
Subject: [PATCH 04/15] Toggle-able Basit Mode (#3672)
* Some updates to Basit Mode. Added it to the 6 key
* Renamed BasitMode to ColorsMode
---
.../src/Extensions/ViewModesKeys.ts | 3 ++
packages/viewer-sandbox/src/main.ts | 8 +++-
packages/viewer/src/index.ts | 2 +
.../src/modules/extensions/ViewModes.ts | 7 +++-
.../src/modules/pipeline/Passes/BasitPass.ts | 7 ++--
.../pipeline/Pipelines/BasitViewPipeline.ts | 39 ++++++++++++++++---
6 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/packages/viewer-sandbox/src/Extensions/ViewModesKeys.ts b/packages/viewer-sandbox/src/Extensions/ViewModesKeys.ts
index 34eb55f13..ef97376fe 100644
--- a/packages/viewer-sandbox/src/Extensions/ViewModesKeys.ts
+++ b/packages/viewer-sandbox/src/Extensions/ViewModesKeys.ts
@@ -31,6 +31,9 @@ export class ViewModesKeys extends Extension {
case '5':
viewModes.setViewMode(ViewMode.ARCTIC)
break
+ case '6':
+ viewModes.setViewMode(ViewMode.COLORS)
+ break
}
})
}
diff --git a/packages/viewer-sandbox/src/main.ts b/packages/viewer-sandbox/src/main.ts
index afe349945..310360f41 100644
--- a/packages/viewer-sandbox/src/main.ts
+++ b/packages/viewer-sandbox/src/main.ts
@@ -11,7 +11,6 @@ import {
import './style.css'
import Sandbox from './Sandbox'
import {
- SelectionExtension,
MeasurementsExtension,
ExplodeExtension,
DiffExtension,
@@ -456,7 +455,12 @@ const getStream = () => {
// 'https://app.speckle.systems/projects/344f803f81/models/5582ab673e'
// 'https://speckle.xyz/streams/27e89d0ad6/commits/5ed4b74252'
- 'https://app.speckle.systems/projects/e89b61b65c/models/2a0995f124'
+
+ // DUI3 Mesh Colors
+ 'https://app.speckle.systems/projects/93200a735d/models/cbacd3eaeb@344a397239'
+
+ // Instance toilets
+ // 'https://app.speckle.systems/projects/e89b61b65c/models/2a0995f124'
)
}
diff --git a/packages/viewer/src/index.ts b/packages/viewer/src/index.ts
index 0a558915b..668ebbe82 100644
--- a/packages/viewer/src/index.ts
+++ b/packages/viewer/src/index.ts
@@ -131,6 +131,7 @@ import {
} from './modules/materials/Materials.js'
import { AccelerationStructure } from './modules/objects/AccelerationStructure.js'
import { TopLevelAccelerationStructure } from './modules/objects/TopLevelAccelerationStructure.js'
+import { BasitPipeline } from './modules/pipeline/Pipelines/BasitViewPipeline.js'
export {
Viewer,
@@ -214,6 +215,7 @@ export {
MRTEdgesPipeline,
MRTShadedViewPipeline,
MRTPenViewPipeline,
+ BasitPipeline,
ViewModes,
ViewMode,
FilterMaterial,
diff --git a/packages/viewer/src/modules/extensions/ViewModes.ts b/packages/viewer/src/modules/extensions/ViewModes.ts
index c1e2a8281..f4c84824c 100644
--- a/packages/viewer/src/modules/extensions/ViewModes.ts
+++ b/packages/viewer/src/modules/extensions/ViewModes.ts
@@ -1,5 +1,6 @@
import { UpdateFlags } from '../../IViewer.js'
import { ArcticViewPipeline } from '../pipeline/Pipelines/ArcticViewPipeline.js'
+import { BasitPipeline } from '../pipeline/Pipelines/BasitViewPipeline.js'
import { DefaultPipeline } from '../pipeline/Pipelines/DefaultPipeline.js'
import { EdgesPipeline } from '../pipeline/Pipelines/EdgesPipeline.js'
import { MRTEdgesPipeline } from '../pipeline/Pipelines/MRT/MRTEdgesPipeline.js'
@@ -14,7 +15,8 @@ export enum ViewMode {
DEFAULT_EDGES,
SHADED,
PEN,
- ARCTIC
+ ARCTIC,
+ COLORS
}
export class ViewModes extends Extension {
@@ -46,6 +48,9 @@ export class ViewModes extends Extension {
case ViewMode.ARCTIC:
renderer.pipeline = new ArcticViewPipeline(renderer)
break
+ case ViewMode.COLORS:
+ renderer.pipeline = new BasitPipeline(renderer, this.viewer.getWorldTree())
+ break
}
this.viewer.requestRender(UpdateFlags.RENDER_RESET)
}
diff --git a/packages/viewer/src/modules/pipeline/Passes/BasitPass.ts b/packages/viewer/src/modules/pipeline/Passes/BasitPass.ts
index 37cc61718..2bdf9f89b 100644
--- a/packages/viewer/src/modules/pipeline/Passes/BasitPass.ts
+++ b/packages/viewer/src/modules/pipeline/Passes/BasitPass.ts
@@ -32,13 +32,14 @@ export class BasitPass extends BaseGPass {
super()
this.tree = tree
this.speckleRenderer = renderer
+ this.buildMaterials()
}
public get displayName(): string {
return 'BASIT'
}
- onBeforeRender = () => {
+ protected buildMaterials() {
const batches: MeshBatch[] = this.speckleRenderer.batcher.getBatches(
undefined,
GeometryType.MESH
@@ -112,14 +113,14 @@ export class BasitPass extends BaseGPass {
protected overrideMaterials() {
for (const k in this.materialMap) {
const tuple = this.materialMap[k]
- ;(tuple[0].renderObject as SpeckleMesh).setOverrideMaterial(tuple[2])
+ ;(tuple[0].renderObject as SpeckleMesh).setOverrideBatchMaterial(tuple[2])
}
}
protected restoreMaterials() {
for (const k in this.materialMap) {
const tuple = this.materialMap[k]
- ;(tuple[0].renderObject as SpeckleMesh).restoreMaterial()
+ ;(tuple[0].renderObject as SpeckleMesh).restoreBatchMaterial()
}
}
diff --git a/packages/viewer/src/modules/pipeline/Pipelines/BasitViewPipeline.ts b/packages/viewer/src/modules/pipeline/Pipelines/BasitViewPipeline.ts
index 559e0cae8..b93b22c62 100644
--- a/packages/viewer/src/modules/pipeline/Pipelines/BasitViewPipeline.ts
+++ b/packages/viewer/src/modules/pipeline/Pipelines/BasitViewPipeline.ts
@@ -3,7 +3,9 @@ import SpeckleRenderer from '../../SpeckleRenderer.js'
import { GeometryPass } from '../Passes/GeometryPass.js'
import { Pipeline } from './Pipeline.js'
import { BasitPass } from '../Passes/BasitPass.js'
-import { ClearFlags } from '../Passes/GPass.js'
+import { ClearFlags, ObjectVisibility } from '../Passes/GPass.js'
+import { StencilPass } from '../Passes/StencilPass.js'
+import { StencilMaskPass } from '../Passes/StencilMaskPass.js'
export class BasitPipeline extends Pipeline {
constructor(speckleRenderer: SpeckleRenderer, tree: WorldTree) {
@@ -12,13 +14,38 @@ export class BasitPipeline extends Pipeline {
const basitPass = new BasitPass(tree, speckleRenderer)
basitPass.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
basitPass.setClearColor(0x000000, 0)
- basitPass.setClearFlags(ClearFlags.COLOR | ClearFlags.DEPTH | ClearFlags.STENCIL)
+ basitPass.setClearFlags(ClearFlags.COLOR)
basitPass.outputTarget = null
- const transparentColorPass = new GeometryPass()
- transparentColorPass.setLayers([ObjectLayers.SHADOWCATCHER])
- transparentColorPass.outputTarget = null
+ const nonMeshPass = new GeometryPass()
+ nonMeshPass.setLayers([
+ ObjectLayers.STREAM_CONTENT_LINE,
+ ObjectLayers.STREAM_CONTENT_POINT,
+ ObjectLayers.STREAM_CONTENT_POINT_CLOUD,
+ ObjectLayers.STREAM_CONTENT_TEXT
+ ])
+ const stencilPass = new StencilPass()
+ stencilPass.setVisibility(ObjectVisibility.STENCIL)
+ stencilPass.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
- this.passList.push(basitPass, transparentColorPass)
+ const stencilMaskPass = new StencilMaskPass()
+ stencilMaskPass.setVisibility(ObjectVisibility.STENCIL)
+ stencilMaskPass.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
+ stencilMaskPass.setClearFlags(ClearFlags.DEPTH)
+
+ const overlayPass = new GeometryPass()
+ overlayPass.setLayers([
+ ObjectLayers.PROPS,
+ ObjectLayers.OVERLAY,
+ ObjectLayers.MEASUREMENTS
+ ])
+
+ this.passList.push(
+ stencilPass,
+ basitPass,
+ nonMeshPass,
+ stencilMaskPass,
+ overlayPass
+ )
}
}
From 222f3ddb5b323f5e0ce829918efcae9da732da4e Mon Sep 17 00:00:00 2001
From: Mike
Date: Thu, 12 Dec 2024 15:44:42 +0100
Subject: [PATCH 05/15] Feat: Add upgraded and failed event (#3683)
---
.../frontend-2/lib/billing/composables/actions.ts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/packages/frontend-2/lib/billing/composables/actions.ts b/packages/frontend-2/lib/billing/composables/actions.ts
index b8b230d4f..fed3dbd58 100644
--- a/packages/frontend-2/lib/billing/composables/actions.ts
+++ b/packages/frontend-2/lib/billing/composables/actions.ts
@@ -199,12 +199,24 @@ export const useBillingActions = () => {
type: ToastNotificationType.Danger,
title: 'Your payment was canceled'
})
+
+ mixpanel.track('Workspace Upgrade Cancelled', {
+ // eslint-disable-next-line camelcase
+ workspace_id: workspace.id
+ })
} else {
triggerNotification({
type: ToastNotificationType.Success,
title: 'Your workspace plan was successfully updated'
})
+ mixpanel.track('Workspace Upgraded', {
+ plan: workspace.plan?.name,
+ cycle: workspace.subscription?.billingInterval,
+ // eslint-disable-next-line camelcase
+ workspace_id: workspace.id
+ })
+
if (import.meta.server) {
await sendWebhook(defaultZapierWebhookUrl, {
workspaceId: workspace.id,
From ad61f1d885d06fc97c682c8cf9b0e7002e065300 Mon Sep 17 00:00:00 2001
From: Mike
Date: Thu, 12 Dec 2024 16:12:32 +0100
Subject: [PATCH 06/15] Feat: Change server invite to new design (#3676)
---
.../components/form/select/ServerRoles.vue | 5 +-
.../components/header/NavUserMenu.vue | 2 +-
.../components/invite/dialog/Server.vue | 176 ++++++++++++++++++
.../components/onboarding/checklist/v1.vue | 2 +-
.../settings/server/ActiveUsers.vue | 2 +-
.../settings/server/PendingInvitations.vue | 2 +-
.../settings/server/user/InviteDialog.vue | 136 --------------
.../components/singleton/ToastManager.vue | 10 +-
.../lib/common/composables/toast.ts | 99 +++++++---
.../lib/invites/helpers/constants.ts | 8 +
.../frontend-2/lib/invites/helpers/types.ts | 12 ++
.../projects/composables/projectManagement.ts | 10 +-
.../lib/server/composables/invites.ts | 10 +-
.../src/components/form/select/Base.vue | 2 +-
.../global/ToastRenderer.stories.ts | 64 +++----
.../src/components/global/ToastRenderer.vue | 34 ++--
.../ui-components/src/helpers/global/toast.ts | 1 +
.../src/stories/components/GlobalToast.vue | 10 +-
.../src/stories/composables/toast.ts | 97 +++++++---
19 files changed, 415 insertions(+), 267 deletions(-)
create mode 100644 packages/frontend-2/components/invite/dialog/Server.vue
delete mode 100644 packages/frontend-2/components/settings/server/user/InviteDialog.vue
create mode 100644 packages/frontend-2/lib/invites/helpers/constants.ts
create mode 100644 packages/frontend-2/lib/invites/helpers/types.ts
diff --git a/packages/frontend-2/components/form/select/ServerRoles.vue b/packages/frontend-2/components/form/select/ServerRoles.vue
index 25028ebd8..9aa4c2bce 100644
--- a/packages/frontend-2/components/form/select/ServerRoles.vue
+++ b/packages/frontend-2/components/form/select/ServerRoles.vue
@@ -7,7 +7,7 @@
:disabled-item-tooltip="
!allowGuest ? 'The Guest role isn\'t enabled on the server' : ''
"
- name="serverRoles"
+ :name="name ?? 'serverRoles'"
label="Role"
:show-label="showLabel"
class="min-w-[110px]"
@@ -75,7 +75,8 @@ const props = defineProps({
allowAdmin: Boolean,
allowArchived: Boolean,
fullyControlValue: Boolean,
- showLabel: Boolean
+ showLabel: Boolean,
+ name: String
})
const elementToWatchForChanges = ref(null as Nullable)
diff --git a/packages/frontend-2/components/header/NavUserMenu.vue b/packages/frontend-2/components/header/NavUserMenu.vue
index 04a59f813..4083b7035 100644
--- a/packages/frontend-2/components/header/NavUserMenu.vue
+++ b/packages/frontend-2/components/header/NavUserMenu.vue
@@ -124,7 +124,7 @@
-
+
+
+ Invite to Speckle
+
+
+
+
diff --git a/packages/frontend-2/components/onboarding/checklist/v1.vue b/packages/frontend-2/components/onboarding/checklist/v1.vue
index 0dd619fb6..73e647a22 100644
--- a/packages/frontend-2/components/onboarding/checklist/v1.vue
+++ b/packages/frontend-2/components/onboarding/checklist/v1.vue
@@ -213,7 +213,7 @@
>
Your first upload
- (!v ? markComplete(3) : '')"
/>
diff --git a/packages/frontend-2/components/settings/server/ActiveUsers.vue b/packages/frontend-2/components/settings/server/ActiveUsers.vue
index 3d9150edc..da61c5a23 100644
--- a/packages/frontend-2/components/settings/server/ActiveUsers.vue
+++ b/packages/frontend-2/components/settings/server/ActiveUsers.vue
@@ -98,7 +98,7 @@
:user="userToModify"
/>
-
+
diff --git a/packages/frontend-2/components/settings/server/PendingInvitations.vue b/packages/frontend-2/components/settings/server/PendingInvitations.vue
index 2644c0156..844e2801b 100644
--- a/packages/frontend-2/components/settings/server/PendingInvitations.vue
+++ b/packages/frontend-2/components/settings/server/PendingInvitations.vue
@@ -70,7 +70,7 @@
@infinite="onInfiniteLoad"
/>
-
+
diff --git a/packages/frontend-2/components/settings/server/user/InviteDialog.vue b/packages/frontend-2/components/settings/server/user/InviteDialog.vue
deleted file mode 100644
index b8e38bf71..000000000
--- a/packages/frontend-2/components/settings/server/user/InviteDialog.vue
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
- Get your colleagues in!
-
-
-
-
diff --git a/packages/frontend-2/components/singleton/ToastManager.vue b/packages/frontend-2/components/singleton/ToastManager.vue
index 43499b8f7..616aea412 100644
--- a/packages/frontend-2/components/singleton/ToastManager.vue
+++ b/packages/frontend-2/components/singleton/ToastManager.vue
@@ -1,6 +1,6 @@
-
+
@@ -8,13 +8,13 @@
import { useGlobalToastManager } from '~~/lib/common/composables/toast'
import { GlobalToastRenderer } from '@speckle/ui-components'
-const { currentNotification, dismiss } = useGlobalToastManager()
+const { currentNotifications, dismissAll, dismiss } = useGlobalToastManager()
-const notification = computed({
- get: () => currentNotification.value,
+const notifications = computed({
+ get: () => currentNotifications.value,
set: (newVal) => {
if (!newVal) {
- dismiss()
+ dismissAll()
}
}
})
diff --git a/packages/frontend-2/lib/common/composables/toast.ts b/packages/frontend-2/lib/common/composables/toast.ts
index 657afacac..a2b5911c6 100644
--- a/packages/frontend-2/lib/common/composables/toast.ts
+++ b/packages/frontend-2/lib/common/composables/toast.ts
@@ -1,60 +1,93 @@
-import { useTimeoutFn } from '@vueuse/core'
import type { Optional } from '@speckle/shared'
import type { ToastNotification } from '@speckle/ui-components'
+import { useTimeoutFn } from '@vueuse/core'
import { ToastNotificationType } from '@speckle/ui-components'
import { useSynchronizedCookie } from '~/lib/common/composables/reactiveCookie'
+import { nanoid } from 'nanoid'
/**
* Persisting toast state between reqs and between CSR & SSR loads so that we can trigger
* toasts anywhere and anytime
*/
const useGlobalToastState = () =>
- useSynchronizedCookie>('global-toast-state')
+ useSynchronizedCookie>('global-toast-state')
/**
* Set up a new global toast manager/renderer (don't use this in multiple components that live at the same time)
*/
export function useGlobalToastManager() {
- const stateNotification = useGlobalToastState()
-
- const currentNotification = ref(stateNotification.value)
- const readOnlyNotification = computed(() => currentNotification.value)
-
- const dismiss = () => {
- currentNotification.value = undefined
- stateNotification.value = undefined
+ type Timeout = {
+ id: string
+ stop: () => void
}
- const { start, stop } = useTimeoutFn(() => {
- dismiss()
- }, 4000)
+ const stateNotification = useGlobalToastState()
+
+ const timeouts = ref([])
+ const currentNotifications = ref(
+ Array.isArray(stateNotification.value) ? stateNotification.value : []
+ )
+ const readOnlyNotification = computed(() => currentNotifications.value)
+
+ // Remove a specific notification from the state
+ const removeNotification = (id: string) => {
+ const index = currentNotifications.value.findIndex((n) => n.id === id)
+ if (index !== -1) {
+ currentNotifications.value.splice(index, 1)
+ // Clean up timeout
+ timeouts.value = timeouts.value.filter((t) => t.id !== id)
+ }
+ }
+
+ // Create a timeout for a notification
+ const createTimeout = (notification: ToastNotification) => {
+ const { stop } = useTimeoutFn(() => {
+ if (notification.id) {
+ removeNotification(notification.id)
+ }
+ }, 4000)
+ return stop
+ }
watch(
stateNotification,
(newVal) => {
if (!newVal) return
- if (import.meta.server) {
- currentNotification.value = newVal
- return
+ currentNotifications.value = newVal
+
+ // Create timeout for the new notification
+ const index = currentNotifications.value.length - 1
+ const lastNotification = newVal[index]
+
+ if (lastNotification && !lastNotification.autoClose) {
+ timeouts.value.push({
+ id: lastNotification.id as string,
+ stop: createTimeout(lastNotification)
+ })
}
-
- // First dismiss old notification, then set a new one on next tick
- // this is so that the old one actually disappears from the screen for the user,
- // instead of just having its contents replaced
- dismiss()
-
- nextTick(() => {
- currentNotification.value = newVal
-
- // (re-)init timeout
- stop()
- if (newVal.autoClose !== false) start()
- })
},
{ deep: true, immediate: true }
)
- return { currentNotification: readOnlyNotification, dismiss }
+ // Function to dismiss a specific notification
+ const dismiss = (notification: ToastNotification) => {
+ if (!notification.id) return
+
+ const targetTimeout = timeouts.value.find((t) => t.id === notification.id)
+ if (targetTimeout) {
+ targetTimeout.stop()
+ }
+ removeNotification(notification.id as string)
+ }
+
+ // Dismiss all notifications
+ const dismissAll = () => {
+ timeouts.value.forEach((timeout) => timeout.stop())
+ timeouts.value = []
+ currentNotifications.value = []
+ }
+
+ return { currentNotifications: readOnlyNotification, dismiss, dismissAll }
}
/**
@@ -68,7 +101,11 @@ export function useGlobalToast() {
* Trigger a new toast notification
*/
const triggerNotification = (notification: ToastNotification) => {
- stateNotification.value = notification
+ const newNotification = { ...notification, id: nanoid() }
+
+ stateNotification.value
+ ? stateNotification.value.push(newNotification)
+ : (stateNotification.value = [newNotification])
if (import.meta.server) {
logger.info('Queued SSR toast notification', notification)
diff --git a/packages/frontend-2/lib/invites/helpers/constants.ts b/packages/frontend-2/lib/invites/helpers/constants.ts
new file mode 100644
index 000000000..d31c358f6
--- /dev/null
+++ b/packages/frontend-2/lib/invites/helpers/constants.ts
@@ -0,0 +1,8 @@
+import type { InviteServerItem } from '~~/lib/invites/helpers/types'
+import { Roles } from '@speckle/shared'
+
+export const emptyInviteServerItem: InviteServerItem = {
+ email: '',
+ serverRole: Roles.Server.User,
+ project: undefined
+}
diff --git a/packages/frontend-2/lib/invites/helpers/types.ts b/packages/frontend-2/lib/invites/helpers/types.ts
new file mode 100644
index 000000000..aeae0c16a
--- /dev/null
+++ b/packages/frontend-2/lib/invites/helpers/types.ts
@@ -0,0 +1,12 @@
+import type { ServerRoles } from '@speckle/shared'
+import type { FormSelectProjects_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
+
+export type InviteServerItem = {
+ email: string
+ serverRole: ServerRoles
+ project?: FormSelectProjects_ProjectFragment
+}
+
+export interface InviteServerForm {
+ fields: InviteServerItem[]
+}
diff --git a/packages/frontend-2/lib/projects/composables/projectManagement.ts b/packages/frontend-2/lib/projects/composables/projectManagement.ts
index d4520d467..3049df31f 100644
--- a/packages/frontend-2/lib/projects/composables/projectManagement.ts
+++ b/packages/frontend-2/lib/projects/composables/projectManagement.ts
@@ -308,13 +308,19 @@ export function useInviteUserToProject() {
if (err) {
triggerNotification({
type: ToastNotificationType.Danger,
- title: 'Invitation failed',
+ title:
+ input.length > 1
+ ? "Couldn't send invites"
+ : `Coudldn't send invite to ${input[0].email}`,
description: err
})
} else {
triggerNotification({
type: ToastNotificationType.Success,
- title: 'Invite successfully sent'
+ title:
+ input.length > 1
+ ? 'Invites successfully send'
+ : `Invite successfully sent to ${input[0].email}`
})
}
diff --git a/packages/frontend-2/lib/server/composables/invites.ts b/packages/frontend-2/lib/server/composables/invites.ts
index c0b73713d..cd18c3222 100644
--- a/packages/frontend-2/lib/server/composables/invites.ts
+++ b/packages/frontend-2/lib/server/composables/invites.ts
@@ -55,13 +55,19 @@ export function useInviteUserToServer() {
if (res?.data?.serverInviteBatchCreate) {
triggerNotification({
type: ToastNotificationType.Success,
- title: `Server invite${finalInput.length > 1 ? 's' : ''} sent`
+ title:
+ finalInput.length > 1
+ ? 'Server invites sent'
+ : `Server invite sent to ${finalInput[0].email}`
})
} else {
const errMsg = getFirstErrorMessage(res?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
- title: `Couldn't send invite${finalInput.length > 1 ? 's' : ''}`,
+ title:
+ finalInput.length > 1
+ ? "Couldn't send invites"
+ : `Couldn't send invite to ${finalInput[0].email}`,
description: errMsg
})
}
diff --git a/packages/ui-components/src/components/form/select/Base.vue b/packages/ui-components/src/components/form/select/Base.vue
index 3f988eb63..5c72ffc5f 100644
--- a/packages/ui-components/src/components/form/select/Base.vue
+++ b/packages/ui-components/src/components/form/select/Base.vue
@@ -127,7 +127,7 @@
ref="searchInput"
v-model="searchValue"
type="text"
- class="py-1 pl-7 w-full bg-foundation placeholder:font-normal normal placeholder:text-foreground-2 text-[13px]"
+ class="py-1 pl-7 w-full bg-foundation placeholder:font-normal normal placeholder:text-foreground-2 text-[13px] focus-visible:[box-shadow:none] rounded-md hover:border-outline-5 focus-visible:border-outline-4"
:placeholder="searchPlaceholder"
@keydown.stop
/>
diff --git a/packages/ui-components/src/components/global/ToastRenderer.stories.ts b/packages/ui-components/src/components/global/ToastRenderer.stories.ts
index ce1e1fe54..fe7b69219 100644
--- a/packages/ui-components/src/components/global/ToastRenderer.stories.ts
+++ b/packages/ui-components/src/components/global/ToastRenderer.stories.ts
@@ -7,7 +7,7 @@ import { ToastNotificationType } from '~~/src/helpers/global/toast'
import type { ToastNotification } from '~~/src/helpers/global/toast'
import { useGlobalToast } from '~~/src/stories/composables/toast'
-type StoryType = StoryObj<{ notification: ToastNotification }>
+type StoryType = StoryObj<{ notifications: ToastNotification[] }>
export default {
component: ToastRenderer,
@@ -20,12 +20,11 @@ export default {
}
},
argTypes: {
- notification: {
- description: 'ToastNotification type object, nullable'
+ notifications: {
+ description: 'ToastNotification array, nullable'
},
- 'update:notification': {
- description:
- "Notification prop update event. Enables two-way binding through 'v-model:notification'"
+ dismiss: {
+ description: 'Dismiss event for a notification'
}
}
} as Meta
@@ -35,11 +34,11 @@ export const Default: StoryType = {
components: { ToastRenderer, FormButton },
setup() {
const { triggerNotification } = useGlobalToast()
- const notification = ref(null as Nullable)
+ const notifications = ref(null as Nullable)
const onClick = () => {
- triggerNotification(args.notification)
+ triggerNotification(args.notifications[0])
}
- return { args, onClick, notification }
+ return { args, onClick, notifications }
},
template: `
@@ -50,30 +49,34 @@ export const Default: StoryType = {
parameters: {
docs: {
source: {
- code: '
'
+ code: '
'
}
}
},
args: {
- notification: {
- type: ToastNotificationType.Info,
- title: 'Title',
- description: 'Description',
+ notifications: [
+ {
+ type: ToastNotificationType.Info,
+ title: 'Title',
+ description: 'Description',
- cta: {
- title: 'CTA'
+ cta: {
+ title: 'CTA'
+ }
}
- }
+ ]
}
}
export const WithManualClose: StoryType = {
...Default,
args: {
- notification: {
- ...Default.args!.notification!,
- autoClose: false
- }
+ notifications: [
+ {
+ ...Default.args!.notifications![0],
+ autoClose: false
+ }
+ ]
}
}
@@ -81,23 +84,20 @@ export const NoCtaOrDescription: StoryObj = {
render: (args) => ({
components: { ToastRenderer, FormButton },
setup() {
- const notification = ref(null as Nullable
)
+ const { triggerNotification } = useGlobalToast()
+ const notifications = ref(null as Nullable)
const onClick = () => {
- // Update notification without cta or description
- notification.value = {
+ triggerNotification({
type: ToastNotificationType.Info,
title: 'Displays a toast notification'
- }
-
- // Clear after 2s
- setTimeout(() => (notification.value = null), 2000)
+ })
}
- return { args, onClick, notification }
+ return { args, onClick, notifications }
},
template: `
Trigger Title Only
-
+
`
}),
@@ -108,8 +108,8 @@ export const NoCtaOrDescription: StoryObj = {
},
source: {
code: `
-Trigger Title Only
-
+ Trigger Title Only
+
`
}
}
diff --git a/packages/ui-components/src/components/global/ToastRenderer.vue b/packages/ui-components/src/components/global/ToastRenderer.vue
index 01bdc1a82..41d68a501 100644
--- a/packages/ui-components/src/components/global/ToastRenderer.vue
+++ b/packages/ui-components/src/components/global/ToastRenderer.vue
@@ -5,7 +5,7 @@
>
-
@@ -60,7 +61,7 @@
color="subtle"
:to="notification.cta.url"
size="sm"
- @click="onCtaClick"
+ @click="(e: MouseEvent) => onCtaClick(notification, e)"
>
{{ notification.cta.title }}
@@ -70,7 +71,7 @@
-
+
@@ -91,29 +92,24 @@ import {
InformationCircleIcon,
XMarkIcon
} from '@heroicons/vue/20/solid'
-import { computed } from 'vue'
import type { MaybeNullOrUndefined } from '@speckle/shared'
import { ToastNotificationType } from '~~/src/helpers/global/toast'
import type { ToastNotification } from '~~/src/helpers/global/toast'
const emit = defineEmits<{
- (e: 'update:notification', val: MaybeNullOrUndefined): void
+ (e: 'dismiss', val: ToastNotification): void
}>()
-const props = defineProps<{
- notification: MaybeNullOrUndefined
+defineProps<{
+ notifications: MaybeNullOrUndefined
}>()
-const isTitleOnly = computed(
- () => !props.notification?.description && !props.notification?.cta
-)
-
-const dismiss = () => {
- emit('update:notification', null)
+const dismiss = (notification: ToastNotification) => {
+ emit('dismiss', notification)
}
-const onCtaClick = (e: MouseEvent) => {
- props.notification?.cta?.onClick?.(e)
- dismiss()
+const onCtaClick = (notification: ToastNotification, e: MouseEvent) => {
+ notification.cta?.onClick?.(e)
+ dismiss(notification)
}
diff --git a/packages/ui-components/src/helpers/global/toast.ts b/packages/ui-components/src/helpers/global/toast.ts
index 7052f86a2..4c070cf69 100644
--- a/packages/ui-components/src/helpers/global/toast.ts
+++ b/packages/ui-components/src/helpers/global/toast.ts
@@ -25,4 +25,5 @@ export type ToastNotification = {
* Defaults to true
*/
autoClose?: boolean
+ id?: string
}
diff --git a/packages/ui-components/src/stories/components/GlobalToast.vue b/packages/ui-components/src/stories/components/GlobalToast.vue
index 38b795ea8..401583d09 100644
--- a/packages/ui-components/src/stories/components/GlobalToast.vue
+++ b/packages/ui-components/src/stories/components/GlobalToast.vue
@@ -1,18 +1,18 @@
-
+
diff --git a/packages/frontend-2/components/viewer/explode/Menu.vue b/packages/frontend-2/components/viewer/explode/Menu.vue
index 494ddc143..c8112352f 100644
--- a/packages/frontend-2/components/viewer/explode/Menu.vue
+++ b/packages/frontend-2/components/viewer/explode/Menu.vue
@@ -1,53 +1,46 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/packages/frontend-2/components/viewer/menu/Menu.vue b/packages/frontend-2/components/viewer/menu/Menu.vue
new file mode 100644
index 000000000..23cdb98d1
--- /dev/null
+++ b/packages/frontend-2/components/viewer/menu/Menu.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
diff --git a/packages/frontend-2/components/viewer/sun/Menu.vue b/packages/frontend-2/components/viewer/sun/Menu.vue
index a7029b344..8ae8aed37 100644
--- a/packages/frontend-2/components/viewer/sun/Menu.vue
+++ b/packages/frontend-2/components/viewer/sun/Menu.vue
@@ -1,105 +1,111 @@
-
+
+
+
+
+
+
+
+
+ Not available in current view mode.
+
+
+
+
+
+ Sun shadows
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend-2/components/viewer/views/Menu.vue b/packages/frontend-2/components/viewer/views/Menu.vue
index 3280bebad..5c6bbfdcb 100644
--- a/packages/frontend-2/components/viewer/views/Menu.vue
+++ b/packages/frontend-2/components/viewer/views/Menu.vue
@@ -1,52 +1,48 @@
+
-
-
+
+
-
-
+
+
+
diff --git a/packages/frontend-2/lib/viewer/composables/serialization.ts b/packages/frontend-2/lib/viewer/composables/serialization.ts
index 7b3e769f7..5b240f8a1 100644
--- a/packages/frontend-2/lib/viewer/composables/serialization.ts
+++ b/packages/frontend-2/lib/viewer/composables/serialization.ts
@@ -10,7 +10,7 @@ import {
useFilterUtilities,
useSelectionUtilities
} from '~~/lib/viewer/composables/ui'
-import { CameraController } from '@speckle/viewer'
+import { CameraController, ViewMode } from '@speckle/viewer'
import type { NumericPropertyInfo } from '@speckle/viewer'
type SerializedViewerState = SpeckleViewer.ViewerState.SerializedViewerState
@@ -105,6 +105,7 @@ export function useStateSerialization() {
isOrthoProjection: state.ui.camera.isOrthoProjection.value,
zoom: (get(camControls, '_zoom') as number) || 1 // kinda hacky, _zoom is a protected prop
},
+ viewMode: state.ui.viewMode.value,
sectionBox: state.ui.sectionBox.value
? {
min: box.min.toArray(),
@@ -141,7 +142,8 @@ export function useApplySerializedState() {
highlightedObjectIds,
explodeFactor,
lightConfig,
- diff
+ diff,
+ viewMode
},
resources: {
request: { resourceIdString }
@@ -282,6 +284,13 @@ export function useApplySerializedState() {
await endDiff()
}
+ // Restore view mode
+ if (state.ui.viewMode) {
+ viewMode.value = state.ui.viewMode
+ } else {
+ viewMode.value = ViewMode.DEFAULT
+ }
+
explodeFactor.value = state.ui.explodeFactor
lightConfig.value = {
...lightConfig.value,
diff --git a/packages/frontend-2/lib/viewer/composables/setup.ts b/packages/frontend-2/lib/viewer/composables/setup.ts
index 1ea069ea1..cd3705fb2 100644
--- a/packages/frontend-2/lib/viewer/composables/setup.ts
+++ b/packages/frontend-2/lib/viewer/composables/setup.ts
@@ -6,16 +6,17 @@ import {
MeasurementType,
FilteringExtension
} from '@speckle/viewer'
-import type {
- FilteringState,
- PropertyInfo,
- SunLightConfiguration,
- SpeckleView,
- MeasurementOptions,
- DiffResult,
- Viewer,
- WorldTree,
- VisualDiffMode
+import {
+ type FilteringState,
+ type PropertyInfo,
+ type SunLightConfiguration,
+ type SpeckleView,
+ type MeasurementOptions,
+ type DiffResult,
+ type Viewer,
+ type WorldTree,
+ type VisualDiffMode,
+ ViewMode
} from '@speckle/viewer'
import type { MaybeRef } from '@vueuse/shared'
import { inject, ref, provide } from 'vue'
@@ -66,7 +67,6 @@ import {
import { useSynchronizedCookie } from '~~/lib/common/composables/reactiveCookie'
import { buildManualPromise } from '@speckle/ui-components'
import { PassReader } from '../extensions/PassReader'
-import { ViewModesKeys } from '../extensions/ViewModesKeys'
export type LoadedModel = NonNullable<
Get
@@ -259,6 +259,7 @@ export type InjectableViewerState = Readonly<{
target: Ref
isOrthoProjection: Ref
}
+ viewMode: Ref
diff: {
newVersion: ComputedRef
oldVersion: ComputedRef
@@ -338,7 +339,6 @@ function createViewerDataBuilder(params: { viewerDebug: boolean }) {
verbose: !!(import.meta.client && params.viewerDebug)
})
viewer.createExtension(PassReader)
- viewer.createExtension(ViewModesKeys)
const initPromise = viewer.init()
return {
@@ -931,6 +931,7 @@ function setupInterfaceState(
if (explodeFactor.value !== 0) return true
return false
})
+ const viewMode = ref(ViewMode.DEFAULT)
const highlightedObjectIds = ref([] as string[])
const spotlightUserSessionId = ref(null as Nullable)
@@ -993,6 +994,7 @@ function setupInterfaceState(
target,
isOrthoProjection
},
+ viewMode,
sectionBox: ref(null as Nullable),
sectionBoxContext: {
visible: ref(false),
@@ -1078,7 +1080,7 @@ export function useInjectedViewerInterfaceState(): InjectableViewerState['ui'] {
export function useResetUiState() {
const {
- ui: { camera, sectionBox, highlightedObjectIds, lightConfig }
+ ui: { camera, sectionBox, highlightedObjectIds, lightConfig, viewMode }
} = useInjectedViewerState()
const { resetFilters } = useFilterUtilities()
const { endDiff } = useDiffUtilities()
@@ -1088,6 +1090,7 @@ export function useResetUiState() {
sectionBox.value = null
highlightedObjectIds.value = []
lightConfig.value = { ...DefaultLightConfiguration }
+ viewMode.value = ViewMode.DEFAULT
resetFilters()
endDiff()
}
diff --git a/packages/frontend-2/lib/viewer/composables/setup/postSetup.ts b/packages/frontend-2/lib/viewer/composables/setup/postSetup.ts
index 849de3955..26ff1f704 100644
--- a/packages/frontend-2/lib/viewer/composables/setup/postSetup.ts
+++ b/packages/frontend-2/lib/viewer/composables/setup/postSetup.ts
@@ -1,4 +1,10 @@
import { difference, flatten, isEqual, uniq } from 'lodash-es'
+import {
+ ViewMode,
+ type PropertyInfo,
+ type StringPropertyInfo,
+ type SunLightConfiguration
+} from '@speckle/viewer'
import {
ViewerEvent,
VisualDiffMode,
@@ -6,12 +12,9 @@ import {
UpdateFlags,
SectionOutlines,
SectionToolEvent,
- SectionTool
-} from '@speckle/viewer'
-import type {
- PropertyInfo,
- StringPropertyInfo,
- SunLightConfiguration
+ SectionTool,
+ ViewModes,
+ ViewModeEvent
} from '@speckle/viewer'
import { useAuthCookie } from '~~/lib/auth/composables/auth'
import type {
@@ -636,6 +639,44 @@ function useViewerFiltersIntegration() {
)
}
+function useViewerViewModeIntegration() {
+ const {
+ ui: { viewMode },
+ viewer: { instance }
+ } = useInjectedViewerState()
+
+ const viewModes = instance.getExtension(ViewModes)
+ const onViewModeChanged = (mode: ViewMode) => {
+ viewMode.value = mode
+ }
+
+ onMounted(() => {
+ if (!viewMode.value) {
+ viewMode.value = ViewMode.DEFAULT
+ }
+ viewModes.on(ViewModeEvent.Changed, onViewModeChanged)
+ })
+
+ onBeforeUnmount(() => {
+ // Reset view mode to default
+ viewModes.setViewMode(ViewMode.DEFAULT)
+ viewMode.value = ViewMode.DEFAULT
+
+ // Clean up event listener
+ viewModes.removeListener(ViewModeEvent.Changed, onViewModeChanged)
+ })
+
+ watch(
+ () => viewMode.value,
+ (newMode) => {
+ if (viewModes && newMode) {
+ viewModes.setViewMode(newMode)
+ }
+ },
+ { immediate: true }
+ )
+}
+
function useLightConfigIntegration() {
const {
ui: { lightConfig },
@@ -874,6 +915,7 @@ export function useViewerPostSetup() {
useViewerSectionBoxIntegration()
useViewerCameraIntegration()
useViewerFiltersIntegration()
+ useViewerViewModeIntegration()
useLightConfigIntegration()
useExplodeFactorIntegration()
useDiffingIntegration()
diff --git a/packages/frontend-2/lib/viewer/composables/ui.ts b/packages/frontend-2/lib/viewer/composables/ui.ts
index b105335a2..c38a63a50 100644
--- a/packages/frontend-2/lib/viewer/composables/ui.ts
+++ b/packages/frontend-2/lib/viewer/composables/ui.ts
@@ -1,9 +1,14 @@
import { SpeckleViewer, timeoutAt } from '@speckle/shared'
-import type { TreeNode, MeasurementOptions, PropertyInfo } from '@speckle/viewer'
-import { MeasurementsExtension } from '@speckle/viewer'
+import type {
+ TreeNode,
+ MeasurementOptions,
+ PropertyInfo,
+ ViewMode
+} from '@speckle/viewer'
+import { MeasurementsExtension, ViewModes } from '@speckle/viewer'
import { until } from '@vueuse/shared'
import { difference, isString, uniq } from 'lodash-es'
-import { useEmbedState } from '~/lib/viewer/composables/setup/embed'
+import { useEmbedState, useEmbed } from '~/lib/viewer/composables/setup/embed'
import type { SpeckleObject } from '~/lib/viewer/helpers/sceneExplorer'
import { isNonNullable } from '~~/lib/common/helpers/utils'
import {
@@ -15,6 +20,13 @@ import {
import { useDiffBuilderUtilities } from '~~/lib/viewer/composables/setup/diff'
import { useTourStageState } from '~~/lib/viewer/composables/tour'
import { Vector3, Box3 } from 'three'
+import { getKeyboardShortcutTitle, onKeyboardShortcut } from '@speckle/ui-components'
+import { ViewerShortcuts } from '~/lib/viewer/helpers/shortcuts/shortcuts'
+import type {
+ ViewerShortcut,
+ ViewerShortcutAction
+} from '~/lib/viewer/helpers/shortcuts/types'
+import { useActiveElement } from '@vueuse/core'
export function useSectionBoxUtilities() {
const { instance } = useInjectedViewer()
@@ -475,3 +487,93 @@ export function useHighlightedObjectsUtilities() {
clearHighlightedObjects
}
}
+
+export function useViewModeUtilities() {
+ const { instance } = useInjectedViewer()
+ const { viewMode } = useInjectedViewerInterfaceState()
+
+ const currentViewMode = computed(() => viewMode.value)
+
+ const setViewMode = (mode: ViewMode) => {
+ const viewModes = instance.getExtension(ViewModes)
+ if (viewModes) {
+ viewModes.setViewMode(mode)
+ }
+ }
+
+ return {
+ currentViewMode,
+ setViewMode
+ }
+}
+
+export function useViewerShortcuts() {
+ const { ui } = useInjectedViewerState()
+ const { isSmallerOrEqualSm } = useIsSmallerOrEqualThanBreakpoint()
+ const { isEnabled: isEmbedEnabled } = useEmbed()
+ const activeElement = useActiveElement()
+
+ const isTypingComment = computed(() => {
+ if (
+ activeElement.value &&
+ (activeElement.value.tagName.toLowerCase() === 'input' ||
+ activeElement.value.tagName.toLowerCase() === 'textarea' ||
+ activeElement.value.getAttribute('contenteditable') === 'true')
+ ) {
+ return true
+ }
+
+ // Check thread editor states
+ const isNewThreadEditorOpen = ui.threads.openThread.newThreadEditor.value
+ const isExistingThreadEditorOpen = !!ui.threads.openThread.thread.value
+
+ return isNewThreadEditorOpen || isExistingThreadEditorOpen
+ })
+
+ const formatKey = (key: string) => {
+ if (key.startsWith('Digit')) {
+ return key.slice(5)
+ }
+ return key
+ }
+
+ const getShortcutDisplayText = (
+ shortcut: ViewerShortcut,
+ options?: { hideName?: boolean }
+ ) => {
+ if (isSmallerOrEqualSm.value) return undefined
+ if (isEmbedEnabled.value) return undefined
+
+ const shortcutText = getKeyboardShortcutTitle([
+ ...shortcut.modifiers,
+ formatKey(shortcut.key)
+ ])
+
+ if (!options?.hideName) {
+ return `${shortcut.name} (${shortcutText})`
+ }
+
+ return shortcutText
+ }
+
+ const disableShortcuts = computed(() => isTypingComment.value || isEmbedEnabled.value)
+
+ const registerShortcuts = (
+ handlers: Partial void>>
+ ) => {
+ Object.values(ViewerShortcuts).forEach((shortcut) => {
+ const handler = handlers[shortcut.action as ViewerShortcutAction]
+ if (handler) {
+ onKeyboardShortcut([...shortcut.modifiers], shortcut.key, () => {
+ if (!disableShortcuts.value) handler()
+ })
+ }
+ })
+ }
+
+ return {
+ shortcuts: ViewerShortcuts,
+ registerShortcuts,
+ getShortcutDisplayText
+ }
+}
diff --git a/packages/frontend-2/lib/viewer/extensions/ViewModesKeys.ts b/packages/frontend-2/lib/viewer/extensions/ViewModesKeys.ts
deleted file mode 100644
index df714c2a6..000000000
--- a/packages/frontend-2/lib/viewer/extensions/ViewModesKeys.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import {
- Extension,
- InputEvent,
- ViewMode,
- ViewModes,
- type IViewer
-} from '@speckle/viewer'
-
-export class ViewModesKeys extends Extension {
- public get inject() {
- return [ViewModes]
- }
-
- constructor(viewer: IViewer, protected viewModes: ViewModes) {
- super(viewer)
- const renderer = viewer.getRenderer()
-
- renderer.input.on(InputEvent.KeyUp, (arg: KeyboardEvent) => {
- // Dont trigger on inputs, textareas or contenteditable elements
- // We should handle this more gracefully but it works for now
- if (
- arg.target &&
- ((arg.target as HTMLElement).tagName.toLowerCase() === 'input' ||
- (arg.target as HTMLElement).tagName.toLowerCase() === 'textarea' ||
- (arg.target as HTMLElement).getAttribute('contenteditable') === 'true')
- )
- return
-
- switch (arg.key) {
- case '1':
- viewModes.setViewMode(ViewMode.DEFAULT)
- break
- case '2':
- viewModes.setViewMode(ViewMode.DEFAULT_EDGES)
- break
- case '3':
- viewModes.setViewMode(ViewMode.SHADED)
- break
- case '4':
- viewModes.setViewMode(ViewMode.PEN)
- break
- case '5':
- viewModes.setViewMode(ViewMode.ARCTIC)
- break
- }
- })
- }
-}
diff --git a/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts
new file mode 100644
index 000000000..fa06ee984
--- /dev/null
+++ b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts
@@ -0,0 +1,153 @@
+import { ModifierKeys } from '@speckle/ui-components'
+import { ViewMode } from '@speckle/viewer'
+
+export const PanelShortcuts = {
+ ToggleModels: {
+ name: 'Models',
+ description: 'Toggle models panel',
+ modifiers: [ModifierKeys.Shift],
+ key: 'M',
+ action: 'ToggleModels'
+ },
+ ToggleExplorer: {
+ name: 'Scene explorer',
+ description: 'Toggle scene explorer panel',
+ modifiers: [ModifierKeys.Shift],
+ key: 'E',
+ action: 'ToggleExplorer'
+ },
+ ToggleDiscussions: {
+ name: 'Discussions',
+ description: 'Toggle discussions panel',
+ modifiers: [ModifierKeys.Shift],
+ key: 'D',
+ action: 'ToggleDiscussions'
+ }
+} as const
+
+export const ToolShortcuts = {
+ ToggleMeasurements: {
+ name: 'Measure',
+ description: 'Toggle measurement mode',
+ modifiers: [ModifierKeys.Shift],
+ key: 'R',
+ action: 'ToggleMeasurements'
+ },
+ ToggleProjection: {
+ name: 'Projection',
+ description: 'Toggle between orthographic and perspective projection',
+ modifiers: [ModifierKeys.Shift],
+ key: 'P',
+ action: 'ToggleProjection'
+ },
+ ToggleSectionBox: {
+ name: 'Section',
+ description: 'Toggle section box',
+ modifiers: [ModifierKeys.Shift],
+ key: 'B',
+ action: 'ToggleSectionBox'
+ },
+ ZoomExtentsOrSelection: {
+ name: 'Fit',
+ description: 'Zoom to fit selection or entire model',
+ modifiers: [ModifierKeys.Shift],
+ key: 'space',
+ action: 'ZoomExtentsOrSelection'
+ }
+} as const
+
+export const ViewModeShortcuts = {
+ SetViewModeDefault: {
+ name: 'Default',
+ description: 'Set view mode to Default',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit1',
+ action: 'SetViewModeDefault',
+ viewMode: ViewMode.DEFAULT
+ },
+ SetViewModeDefaultEdges: {
+ name: 'Default + Edges',
+ description: 'Set view mode to Default + Edges',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit2',
+ action: 'SetViewModeDefaultEdges',
+ viewMode: ViewMode.DEFAULT_EDGES
+ },
+ SetViewModeShaded: {
+ name: 'Shaded',
+ description: 'Set view mode to Shaded',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit3',
+ action: 'SetViewModeShaded',
+ viewMode: ViewMode.SHADED
+ },
+ SetViewModePen: {
+ name: 'Pen',
+ description: 'Set view mode to Pen',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit4',
+ action: 'SetViewModePen',
+ viewMode: ViewMode.PEN
+ },
+ SetViewModeArctic: {
+ name: 'Arctic',
+ description: 'Set view mode to Arctic',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit5',
+ action: 'SetViewModeArctic',
+ viewMode: ViewMode.ARCTIC
+ },
+ SetViewModeColors: {
+ name: 'Colors',
+ description: 'Set view mode to Colors',
+ modifiers: [ModifierKeys.Shift],
+ key: 'Digit6',
+ action: 'SetViewModeColors',
+ viewMode: ViewMode.COLORS
+ }
+} as const
+
+export const ViewShortcuts = {
+ SetViewTop: {
+ name: 'Top',
+ description: 'Set view to Top',
+ modifiers: [ModifierKeys.AltOrOpt],
+ key: 'Digit1',
+ action: 'SetViewTop'
+ },
+ SetViewFront: {
+ name: 'Front',
+ description: 'Set view to Front',
+ modifiers: [ModifierKeys.AltOrOpt],
+ key: 'Digit2',
+ action: 'SetViewFront'
+ },
+ SetViewLeft: {
+ name: 'Left',
+ description: 'Set view to Left',
+ modifiers: [ModifierKeys.AltOrOpt],
+ key: 'Digit3',
+ action: 'SetViewLeft'
+ },
+ SetViewBack: {
+ name: 'Back',
+ description: 'Set view to Back',
+ modifiers: [ModifierKeys.AltOrOpt],
+ key: 'Digit4',
+ action: 'SetViewBack'
+ },
+ SetViewRight: {
+ name: 'Right',
+ description: 'Set view to Right',
+ modifiers: [ModifierKeys.AltOrOpt],
+ key: 'Digit5',
+ action: 'SetViewRight'
+ }
+} as const
+
+export const ViewerShortcuts = {
+ ...ViewModeShortcuts,
+ ...PanelShortcuts,
+ ...ToolShortcuts,
+ ...ViewShortcuts
+} as const
diff --git a/packages/frontend-2/lib/viewer/helpers/shortcuts/types.ts b/packages/frontend-2/lib/viewer/helpers/shortcuts/types.ts
new file mode 100644
index 000000000..80ce73ad5
--- /dev/null
+++ b/packages/frontend-2/lib/viewer/helpers/shortcuts/types.ts
@@ -0,0 +1,18 @@
+import type { ModifierKeys } from '@speckle/ui-components'
+import type { ViewMode } from '@speckle/viewer'
+import type { ViewerShortcuts } from '~/lib/viewer/helpers/shortcuts/shortcuts'
+
+export type BaseShortcut = {
+ name: string
+ description: string
+ modifiers: readonly ModifierKeys[]
+ key: string
+ action: string
+}
+
+export type ViewModeShortcut = BaseShortcut & {
+ viewMode: ViewMode
+}
+
+export type ViewerShortcut = (typeof ViewerShortcuts)[keyof typeof ViewerShortcuts]
+export type ViewerShortcutAction = keyof typeof ViewerShortcuts
diff --git a/packages/server/modules/comments/services/data.ts b/packages/server/modules/comments/services/data.ts
index 44737e3c7..cd887e2da 100644
--- a/packages/server/modules/comments/services/data.ts
+++ b/packages/server/modules/comments/services/data.ts
@@ -156,6 +156,7 @@ export const convertLegacyDataToStateFactory =
isOrthoProjection: !!data.camPos?.[6],
zoom: data.camPos?.[7] || 1
},
+ viewMode: 0,
sectionBox: sectionBox
? {
min: (sectionBox.min as number[]) || [0, 0, 0],
diff --git a/packages/shared/src/viewer/helpers/state.ts b/packages/shared/src/viewer/helpers/state.ts
index f62f40190..2d9237372 100644
--- a/packages/shared/src/viewer/helpers/state.ts
+++ b/packages/shared/src/viewer/helpers/state.ts
@@ -74,6 +74,7 @@ export type SerializedViewerState = {
isOrthoProjection: boolean
zoom: number
}
+ viewMode: number
sectionBox: Nullable<{
min: number[]
max: number[]
@@ -198,6 +199,7 @@ const initializeMissingData = (state: UnformattedState): SerializedViewerState =
isOrthoProjection: state.ui?.camera?.isOrthoProjection || false,
zoom: state.ui?.camera?.zoom || 1
},
+ viewMode: state.ui?.viewMode || 0,
sectionBox:
state.ui?.sectionBox?.min?.length && state.ui?.sectionBox.max?.length
? {
diff --git a/packages/ui-components/src/helpers/form/input.ts b/packages/ui-components/src/helpers/form/input.ts
index 8f04485d0..27537860b 100644
--- a/packages/ui-components/src/helpers/form/input.ts
+++ b/packages/ui-components/src/helpers/form/input.ts
@@ -9,14 +9,14 @@ export enum ModifierKeys {
export const clientOs = getClientOperatingSystem()
export const ModifierKeyTitles: Record = {
- [ModifierKeys.CtrlOrCmd]: clientOs === OperatingSystem.Mac ? 'Cmd' : 'Ctrl',
- [ModifierKeys.AltOrOpt]: clientOs === OperatingSystem.Mac ? 'Opt' : 'Alt',
- [ModifierKeys.Shift]: 'Shift'
+ [ModifierKeys.CtrlOrCmd]: clientOs === OperatingSystem.Mac ? '⌘' : '⌃',
+ [ModifierKeys.AltOrOpt]: clientOs === OperatingSystem.Mac ? '⌥' : 'Alt',
+ [ModifierKeys.Shift]: '⇧'
}
export function getKeyboardShortcutTitle(keys: Array) {
const isModifierKey = (k: string): k is ModifierKeys =>
(Object.values(ModifierKeys) as string[]).includes(k)
- return keys.map((v) => (isModifierKey(v) ? ModifierKeyTitles[v] : v)).join('+')
+ return keys.map((v) => (isModifierKey(v) ? ModifierKeyTitles[v] : v)).join('')
}
diff --git a/packages/viewer/src/index.ts b/packages/viewer/src/index.ts
index 668ebbe82..1bf58c440 100644
--- a/packages/viewer/src/index.ts
+++ b/packages/viewer/src/index.ts
@@ -131,6 +131,7 @@ import {
} from './modules/materials/Materials.js'
import { AccelerationStructure } from './modules/objects/AccelerationStructure.js'
import { TopLevelAccelerationStructure } from './modules/objects/TopLevelAccelerationStructure.js'
+import { ViewModeEvent, ViewModeEventPayload } from './modules/extensions/ViewModes.js'
import { BasitPipeline } from './modules/pipeline/Pipelines/BasitViewPipeline.js'
export {
@@ -223,7 +224,8 @@ export {
FilterMaterialOptions,
NOT_INTERSECTED,
INTERSECTED,
- CONTAINED
+ CONTAINED,
+ ViewModeEvent
}
export type {
@@ -257,7 +259,8 @@ export type {
SectionToolEventPayload,
CameraEventPayload,
SelectionExtensionOptions,
- DefaultSelectionExtensionOptions
+ DefaultSelectionExtensionOptions,
+ ViewModeEventPayload
}
export * as UrlHelper from './modules/UrlHelper.js'
diff --git a/packages/viewer/src/modules/extensions/ViewModes.ts b/packages/viewer/src/modules/extensions/ViewModes.ts
index f4c84824c..59ead1581 100644
--- a/packages/viewer/src/modules/extensions/ViewModes.ts
+++ b/packages/viewer/src/modules/extensions/ViewModes.ts
@@ -19,7 +19,22 @@ export enum ViewMode {
COLORS
}
+export enum ViewModeEvent {
+ Changed = 'view-mode-changed'
+}
+
+export interface ViewModeEventPayload {
+ [ViewModeEvent.Changed]: ViewMode
+}
+
export class ViewModes extends Extension {
+ public on(
+ eventType: T,
+ listener: (arg: ViewModeEventPayload[T]) => void
+ ): void {
+ super.on(eventType, listener)
+ }
+
public setViewMode(viewMode: ViewMode) {
const renderer = this.viewer.getRenderer()
const isMRTCapable =
@@ -53,5 +68,7 @@ export class ViewModes extends Extension {
break
}
this.viewer.requestRender(UpdateFlags.RENDER_RESET)
+
+ this.emit(ViewModeEvent.Changed, viewMode)
}
}
From b86a5790943154f5f71c877006a321b95c672c0a Mon Sep 17 00:00:00 2001
From: Mike
Date: Fri, 13 Dec 2024 09:58:20 +0100
Subject: [PATCH 08/15] Fix: Remove automations from General settings query
(#3686)
---
.../project/page/settings/general/block/Delete/Delete.vue | 3 ---
.../project/page/settings/general/block/Delete/Dialog.vue | 7 -------
packages/frontend-2/lib/common/generated/gql/gql.ts | 4 ++--
packages/frontend-2/lib/common/generated/gql/graphql.ts | 8 ++++----
4 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/packages/frontend-2/components/project/page/settings/general/block/Delete/Delete.vue b/packages/frontend-2/components/project/page/settings/general/block/Delete/Delete.vue
index a71df99ef..195209419 100644
--- a/packages/frontend-2/components/project/page/settings/general/block/Delete/Delete.vue
+++ b/packages/frontend-2/components/project/page/settings/general/block/Delete/Delete.vue
@@ -39,9 +39,6 @@ graphql(`
workspace {
slug
}
- automations(limit: 0) {
- totalCount
- }
}
`)
diff --git a/packages/frontend-2/components/project/page/settings/general/block/Delete/Dialog.vue b/packages/frontend-2/components/project/page/settings/general/block/Delete/Dialog.vue
index 7edc0d420..30859528b 100644
--- a/packages/frontend-2/components/project/page/settings/general/block/Delete/Dialog.vue
+++ b/packages/frontend-2/components/project/page/settings/general/block/Delete/Dialog.vue
@@ -7,10 +7,6 @@
delete “{{ project.name }}”
and all its contents, including
{{ project.models.totalCount }} {{ modelText }}
-
- and
- {{ project.automations.totalCount }} {{ automationText }}
-
and
{{ project.commentThreads.totalCount }} {{ discussionText }}
@@ -61,9 +57,6 @@ const modelText = computed(() =>
const discussionText = computed(() =>
props.project.commentThreads.totalCount === 1 ? 'discussion' : 'discussions'
)
-const automationText = computed(() =>
- props.project.automations.totalCount === 1 ? 'automation' : 'automations'
-)
const dialogButtons = computed(() => [
{
diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts
index 22f9359ce..84941e186 100644
--- a/packages/frontend-2/lib/common/generated/gql/gql.ts
+++ b/packages/frontend-2/lib/common/generated/gql/gql.ts
@@ -83,7 +83,7 @@ const documents = {
"\n query ProjectPageSettingsCollaboratorsWorkspace($workspaceId: String!) {\n workspace(id: $workspaceId) {\n ...ProjectPageTeamInternals_Workspace\n }\n }\n": types.ProjectPageSettingsCollaboratorsWorkspaceDocument,
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n role\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": types.ProjectPageSettingsGeneralDocument,
"\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n }\n": types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
- "\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n automations(limit: 0) {\n totalCount\n }\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
+ "\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDiscussions_Project on Project {\n id\n visibility\n allowPublicComments\n }\n": types.ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockLeave_Project on Project {\n id\n name\n role\n team {\n role\n user {\n ...LimitedUserAvatar\n role\n }\n }\n workspace {\n id\n }\n }\n": types.ProjectPageSettingsGeneralBlockLeave_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockProjectInfo_Project on Project {\n id\n role\n name\n description\n }\n": types.ProjectPageSettingsGeneralBlockProjectInfo_ProjectFragmentDoc,
@@ -674,7 +674,7 @@ export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockAcc
/**
* 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 ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n automations(limit: 0) {\n totalCount\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n automations(limit: 0) {\n totalCount\n }\n }\n"];
+export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n id\n name\n role\n models(limit: 0) {\n totalCount\n }\n commentThreads(limit: 0) {\n totalCount\n }\n workspace {\n slug\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 848196eb2..b44de5b36 100644
--- a/packages/frontend-2/lib/common/generated/gql/graphql.ts
+++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts
@@ -4757,11 +4757,11 @@ export type ProjectPageSettingsGeneralQueryVariables = Exact<{
}>;
-export type ProjectPageSettingsGeneralQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, role?: string | null, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, team: Array<{ __typename?: 'ProjectCollaborator', role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null, models: { __typename?: 'ModelCollection', totalCount: number }, commentThreads: { __typename?: 'ProjectCommentCollection', totalCount: number }, automations: { __typename?: 'AutomationCollection', totalCount: number }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } };
+export type ProjectPageSettingsGeneralQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, role?: string | null, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, team: Array<{ __typename?: 'ProjectCollaborator', role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null, models: { __typename?: 'ModelCollection', totalCount: number }, commentThreads: { __typename?: 'ProjectCommentCollection', totalCount: number }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } };
export type ProjectPageSettingsGeneralBlockAccess_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility };
-export type ProjectPageSettingsGeneralBlockDelete_ProjectFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, commentThreads: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', slug: string } | null, automations: { __typename?: 'AutomationCollection', totalCount: number } };
+export type ProjectPageSettingsGeneralBlockDelete_ProjectFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, commentThreads: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', slug: string } | null };
export type ProjectPageSettingsGeneralBlockDiscussions_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, allowPublicComments: boolean };
@@ -6411,7 +6411,7 @@ export const ProjectPageModelsActionsFragmentDoc = {"kind":"Document","definitio
export const ProjectPageLatestItemsModelItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","alias":{"kind":"Name","value":"versionCount"},"name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"commentThreadCount"},"name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedVersions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions"}},{"kind":"Field","name":{"kind":"Name","value":"automationsStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FunctionRunStatusForSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"FunctionRunStatusForSummary"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"results"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"statusMessage"}},{"kind":"Field","name":{"kind":"Name","value":"contextView"}},{"kind":"Field","name":{"kind":"Name","value":"function"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PendingFileUpload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FileUpload"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"modelName"}},{"kind":"Field","name":{"kind":"Name","value":"convertedStatus"}},{"kind":"Field","name":{"kind":"Name","value":"convertedMessage"}},{"kind":"Field","name":{"kind":"Name","value":"uploadDate"}},{"kind":"Field","name":{"kind":"Name","value":"convertedLastUpdate"}},{"kind":"Field","name":{"kind":"Name","value":"fileType"}},{"kind":"Field","name":{"kind":"Name","value":"fileName"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"}}]}}]} as unknown as DocumentNode;
export const SingleLevelModelTreeItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SingleLevelModelTreeItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ModelsTreeItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"model"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"}}]}},{"kind":"Field","name":{"kind":"Name","value":"hasChildren"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PendingFileUpload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FileUpload"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"modelName"}},{"kind":"Field","name":{"kind":"Name","value":"convertedStatus"}},{"kind":"Field","name":{"kind":"Name","value":"convertedMessage"}},{"kind":"Field","name":{"kind":"Name","value":"uploadDate"}},{"kind":"Field","name":{"kind":"Name","value":"convertedLastUpdate"}},{"kind":"Field","name":{"kind":"Name","value":"fileType"}},{"kind":"Field","name":{"kind":"Name","value":"fileName"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FunctionRunStatusForSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"FunctionRunStatusForSummary"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"results"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"statusMessage"}},{"kind":"Field","name":{"kind":"Name","value":"contextView"}},{"kind":"Field","name":{"kind":"Name","value":"function"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","alias":{"kind":"Name","value":"versionCount"},"name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"commentThreadCount"},"name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedVersions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions"}},{"kind":"Field","name":{"kind":"Name","value":"automationsStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"}}]}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}}]}}]} as unknown as DocumentNode;
-export const ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"automations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode;
+export const ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockLeave_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockProjectInfo_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}}]} as unknown as DocumentNode;
@@ -6525,7 +6525,7 @@ export const RequestVerificationDocument = {"kind":"Document","definitions":[{"k
export const AutomationCreateDialogFunctionsSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AutomationCreateDialogFunctionsSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}},"defaultValue":{"kind":"NullValue"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"automateFunctions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"20"}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}}]}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateAutomationCreateDialog_AutomateFunction"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsFunctionsCard_AutomateFunction"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"isFeatured"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"repo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"owner"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateAutomationCreateDialogFunctionParametersStep_AutomateFunction"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"releases"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inputSchema"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateAutomationCreateDialog_AutomateFunction"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsFunctionsCard_AutomateFunction"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateAutomationCreateDialogFunctionParametersStep_AutomateFunction"}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageInviteDialog_Project"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageInviteDialog_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"defaultProjectRole"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domainBasedMembershipProtectionEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"domains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsCollaboratorsWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsCollaboratorsWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Workspace"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Workspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode;
-export const ProjectPageSettingsGeneralDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsGeneral"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"automations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}}]} as unknown as DocumentNode;
+export const ProjectPageSettingsGeneralDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsGeneral"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}}]} as unknown as DocumentNode;
export const OnUserProjectsUpdateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OnUserProjectsUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userProjectsUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectDashboardItem"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsPageTeamDialogManagePermissions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsModelPageEmbed_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsPageTeamDialogManagePermissions_Project"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsModelPageEmbed_Project"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions_Project"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectDashboardItemNoModels"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardProject"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PendingFileUpload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FileUpload"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"modelName"}},{"kind":"Field","name":{"kind":"Name","value":"convertedStatus"}},{"kind":"Field","name":{"kind":"Name","value":"convertedMessage"}},{"kind":"Field","name":{"kind":"Name","value":"uploadDate"}},{"kind":"Field","name":{"kind":"Name","value":"convertedLastUpdate"}},{"kind":"Field","name":{"kind":"Name","value":"fileType"}},{"kind":"Field","name":{"kind":"Name","value":"fileName"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FunctionRunStatusForSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"FunctionRunStatusForSummary"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"results"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"statusMessage"}},{"kind":"Field","name":{"kind":"Name","value":"contextView"}},{"kind":"Field","name":{"kind":"Name","value":"function"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","alias":{"kind":"Name","value":"versionCount"},"name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"commentThreadCount"},"name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedVersions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions"}},{"kind":"Field","name":{"kind":"Name","value":"automationsStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectDashboardItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectDashboardItemNoModels"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"4"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedModels"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"4"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}}]}}]} as unknown as DocumentNode;
export const ProjectsMoveToWorkspaceDialogDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectsMoveToWorkspaceDialog"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsMoveToWorkspaceDialog_User"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceHasCustomDataResidency_Workspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRegion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsWorkspaceSelect_Workspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsMoveToWorkspaceDialog_Workspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceHasCustomDataResidency_Workspace"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsWorkspaceSelect_Workspace"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsMoveToWorkspaceDialog_User"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsMoveToWorkspaceDialog_Workspace"}}]}}]}}]}}]} as unknown as DocumentNode;
export const SettingsServerRegionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SettingsServerRegions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"multiRegion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"regions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SettingsServerRegionsTable_ServerRegionItem"}}]}},{"kind":"Field","name":{"kind":"Name","value":"availableKeys"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SettingsServerRegionsTable_ServerRegionItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ServerRegionItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}}]} as unknown as DocumentNode;
From f1a9a379ef99824afa8d81c7712043b531691756 Mon Sep 17 00:00:00 2001
From: Iain Sproat <68657+iainsproat@users.noreply.github.com>
Date: Fri, 13 Dec 2024 09:54:24 +0000
Subject: [PATCH 09/15] fix(server): use correct types for Timeout (#3687)
---
packages/server/test/notificationsHelper.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/server/test/notificationsHelper.ts b/packages/server/test/notificationsHelper.ts
index 762456fab..2d70d10ae 100644
--- a/packages/server/test/notificationsHelper.ts
+++ b/packages/server/test/notificationsHelper.ts
@@ -57,7 +57,7 @@ export function buildNotificationsStateTracker() {
* Wait for an acknowledgement of a specific msg
*/
waitForMsgAck: async (msgId: JobId, timeout = 2000) => {
- let timeoutRef: NodeJS.Timer
+ let timeoutRef: NodeJS.Timeout
let eventEmitterHandler: (e: AckEvent) => void
return new Promise((resolve, reject) => {
// Set ack cb for notifications event handler
From 09cc2a21c357676cf9283511479f4b9352b3c1cf Mon Sep 17 00:00:00 2001
From: Benjamin Ottensten
Date: Fri, 13 Dec 2024 10:58:50 +0100
Subject: [PATCH 10/15] Update view mode names (#3688)
---
.../lib/viewer/helpers/shortcuts/shortcuts.ts | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts
index fa06ee984..31757dc0d 100644
--- a/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts
+++ b/packages/frontend-2/lib/viewer/helpers/shortcuts/shortcuts.ts
@@ -58,24 +58,24 @@ export const ToolShortcuts = {
export const ViewModeShortcuts = {
SetViewModeDefault: {
- name: 'Default',
- description: 'Set view mode to Default',
+ name: 'Rendered',
+ description: 'Set view mode to Rendered',
modifiers: [ModifierKeys.Shift],
key: 'Digit1',
action: 'SetViewModeDefault',
viewMode: ViewMode.DEFAULT
},
SetViewModeDefaultEdges: {
- name: 'Default + Edges',
- description: 'Set view mode to Default + Edges',
+ name: 'Rendered + Edges',
+ description: 'Set view mode to Rendered + Edges',
modifiers: [ModifierKeys.Shift],
key: 'Digit2',
action: 'SetViewModeDefaultEdges',
viewMode: ViewMode.DEFAULT_EDGES
},
SetViewModeShaded: {
- name: 'Shaded',
- description: 'Set view mode to Shaded',
+ name: 'Solid',
+ description: 'Set view mode to Solid',
modifiers: [ModifierKeys.Shift],
key: 'Digit3',
action: 'SetViewModeShaded',
@@ -98,8 +98,8 @@ export const ViewModeShortcuts = {
viewMode: ViewMode.ARCTIC
},
SetViewModeColors: {
- name: 'Colors',
- description: 'Set view mode to Colors',
+ name: 'Shaded',
+ description: 'Set view mode to Shaded',
modifiers: [ModifierKeys.Shift],
key: 'Digit6',
action: 'SetViewModeColors',
From a4c33fbd25235e10cac32a3969e74a120204eb4f Mon Sep 17 00:00:00 2001
From: andrewwallacespeckle
<139135120+andrewwallacespeckle@users.noreply.github.com>
Date: Fri, 13 Dec 2024 10:13:59 +0000
Subject: [PATCH 11/15] Update Controls.vue (#3689)
---
packages/frontend-2/components/viewer/Controls.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/frontend-2/components/viewer/Controls.vue b/packages/frontend-2/components/viewer/Controls.vue
index 1b56e1a38..57f0f2ed6 100644
--- a/packages/frontend-2/components/viewer/Controls.vue
+++ b/packages/frontend-2/components/viewer/Controls.vue
@@ -231,7 +231,7 @@
-
+
From bd24ec76c874ae27535cce03fdefb255bd398921 Mon Sep 17 00:00:00 2001
From: Mike
Date: Fri, 13 Dec 2024 11:55:31 +0100
Subject: [PATCH 12/15] Fix: Update Automate run label colors (#3690)
---
.../frontend-2/components/automate/runs/StatusBadge.vue | 6 +++++-
packages/frontend-2/lib/automate/composables/runs.ts | 8 ++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/packages/frontend-2/components/automate/runs/StatusBadge.vue b/packages/frontend-2/components/automate/runs/StatusBadge.vue
index 3e4b2084d..c14e12ef4 100644
--- a/packages/frontend-2/components/automate/runs/StatusBadge.vue
+++ b/packages/frontend-2/components/automate/runs/StatusBadge.vue
@@ -1,5 +1,9 @@
-
+
{{ run.status.toUpperCase() }}
diff --git a/packages/frontend-2/lib/automate/composables/runs.ts b/packages/frontend-2/lib/automate/composables/runs.ts
index 68189ba89..4c7db0119 100644
--- a/packages/frontend-2/lib/automate/composables/runs.ts
+++ b/packages/frontend-2/lib/automate/composables/runs.ts
@@ -94,19 +94,19 @@ export const useAutomationRunDetailsFns = () => {
switch (status) {
case AutomateRunStatus.Pending:
case AutomateRunStatus.Initializing:
- classParts.push('bg-warning-lighter text-warning-darker')
+ classParts.push('bg-warning-lighter')
break
case AutomateRunStatus.Running:
- classParts.push('bg-info-lighter text-info-darker')
+ classParts.push('bg-info-lighter')
break
case AutomateRunStatus.Failed:
case AutomateRunStatus.Exception:
case AutomateRunStatus.Canceled:
case AutomateRunStatus.Timeout:
- classParts.push('bg-danger-lighter text-danger-darker')
+ classParts.push('bg-danger-lighter')
break
case AutomateRunStatus.Succeeded:
- classParts.push('bg-success-lighter text-success-darker')
+ classParts.push('bg-success-lighter')
break
}
From 764c373ade2363ace81b4f4f5fa5ef2af63dfdbd Mon Sep 17 00:00:00 2001
From: Adam Hathcock
Date: Fri, 13 Dec 2024 12:19:07 +0000
Subject: [PATCH 13/15] update ifc importer to have better memory usage (#3691)
Co-authored-by: root
---
packages/fileimport-service/ifc-dotnet/ifc-converter.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/fileimport-service/ifc-dotnet/ifc-converter.csproj b/packages/fileimport-service/ifc-dotnet/ifc-converter.csproj
index 9c8c46297..3183ad96c 100644
--- a/packages/fileimport-service/ifc-dotnet/ifc-converter.csproj
+++ b/packages/fileimport-service/ifc-dotnet/ifc-converter.csproj
@@ -10,7 +10,7 @@
-
+
From eeac2be573b26e765de51919ab19ccf2750478e1 Mon Sep 17 00:00:00 2001
From: andrewwallacespeckle
<139135120+andrewwallacespeckle@users.noreply.github.com>
Date: Fri, 13 Dec 2024 13:36:12 +0000
Subject: [PATCH 14/15] Re-add resize panels (#3692)
---
packages/frontend-2/components/viewer/Controls.vue | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/frontend-2/components/viewer/Controls.vue b/packages/frontend-2/components/viewer/Controls.vue
index 57f0f2ed6..4e483ae3e 100644
--- a/packages/frontend-2/components/viewer/Controls.vue
+++ b/packages/frontend-2/components/viewer/Controls.vue
@@ -164,7 +164,7 @@
-
+
-
+
Date: Fri, 13 Dec 2024 13:42:27 +0000
Subject: [PATCH 15/15] Close control menus on click outside (#3693)
---
.../frontend-2/components/viewer/menu/Menu.vue | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/packages/frontend-2/components/viewer/menu/Menu.vue b/packages/frontend-2/components/viewer/menu/Menu.vue
index 23cdb98d1..cc8587f97 100644
--- a/packages/frontend-2/components/viewer/menu/Menu.vue
+++ b/packages/frontend-2/components/viewer/menu/Menu.vue
@@ -11,6 +11,7 @@
@@ -20,15 +21,28 @@