Merge branch 'main' into andrew/upgrade-diff-extension
This commit is contained in:
@@ -18,10 +18,10 @@ const description = computed(() => {
|
||||
if (!props.planName) return ''
|
||||
|
||||
if (props.planName === WorkspacePlans.Team)
|
||||
return 'Your workspace has reached a usage limit. To keep using Speckle, you can buy the Unlimited projects and models add-on to your current Starter plan, or upgrade to the Business plan.'
|
||||
return 'Your workspace has reached a usage limit. Upgrade to the Business plan to keep using Speckle.'
|
||||
if (props.planName === WorkspacePlans.Pro)
|
||||
return 'Your workspace has reached a usage limit. To keep using Speckle, you can buy the Unlimited projects and models add-on to your current Business plan.'
|
||||
return 'Your workspace has reached a usage limit. Buy the Unlimited projects and models add-on to keep using Speckle.'
|
||||
|
||||
return 'Your workspace has reached a usage limit. To keep using Speckle, you should upgrade your workspace to the Starter or Business plan. Note that both plans can be extended with the Unlimited projects and models add-on.'
|
||||
return 'Your workspace has reached a usage limit. To keep using Speckle, you should upgrade your workspace to the Starter or Business plan.'
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,6 @@ const props = defineProps<{
|
||||
isYearlyIntervalSelected: boolean
|
||||
currency?: Currency
|
||||
tooltip?: string
|
||||
fixedPrice?: string
|
||||
}>()
|
||||
|
||||
const { addonPrices } = useWorkspaceAddonPrices()
|
||||
@@ -40,10 +39,6 @@ const addonPrice = computed(() => {
|
||||
})
|
||||
|
||||
const text = computed(() => {
|
||||
if (props.fixedPrice) {
|
||||
return props.fixedPrice
|
||||
}
|
||||
|
||||
return addonPrice.value
|
||||
? `${addonPrice.value} per editor seat / month`
|
||||
: 'Contact us for pricing'
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
:description="featureMetadata.description"
|
||||
/>
|
||||
</ul>
|
||||
<div v-if="showAddons && displayAddons.length > 0" class="mt-auto lg:h-72 pt-8">
|
||||
<div v-if="showAddons && displayAddons.length > 0" class="mt-auto lg:h-32 pt-8">
|
||||
<h5 class="text-body-2xs mb-2 text-foreground-2">Available add-ons</h5>
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<PricingTableAddon
|
||||
@@ -75,7 +75,6 @@
|
||||
:is-yearly-interval-selected="isYearlyIntervalSelected"
|
||||
:currency="props.currency"
|
||||
:tooltip="addon.tooltip"
|
||||
:fixed-price="addon.fixedPrice"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -145,16 +144,16 @@ const commonFeatures = shallowRef([
|
||||
planLimits.value.projectCount === 1 ? '' : 's'
|
||||
}`,
|
||||
description:
|
||||
props.plan === WorkspacePlans.Free
|
||||
? 'Your maximum number of projects'
|
||||
: 'Your maximum number of projects. Can be extended with the Unlimited projects and models add-on.'
|
||||
props.plan === WorkspacePlans.Pro
|
||||
? 'Your maximum number of projects. Can be extended with the Unlimited projects and models add-on.'
|
||||
: 'Your maximum number of projects'
|
||||
},
|
||||
{
|
||||
displayName: `${planLimits.value.modelCount} models per workspace`,
|
||||
description:
|
||||
props.plan === WorkspacePlans.Free
|
||||
? 'Your maximum number of models'
|
||||
: 'Your maximum number of models. Can be extended with the Unlimited projects and models add-on.'
|
||||
props.plan === WorkspacePlans.Pro
|
||||
? 'Your maximum number of models. Can be extended with the Unlimited projects and models add-on.'
|
||||
: 'Your maximum number of models'
|
||||
},
|
||||
{
|
||||
displayName: planLimits.value.versionsHistory
|
||||
@@ -384,30 +383,13 @@ const badgeText = computed(() =>
|
||||
)
|
||||
|
||||
const displayAddons = computed(() => {
|
||||
if (props.plan === WorkspacePlans.Team) {
|
||||
if (props.plan === WorkspacePlans.Pro) {
|
||||
return [
|
||||
{
|
||||
title: 'Unlimited projects and models',
|
||||
tooltip: 'You can purchase this in the next step'
|
||||
}
|
||||
]
|
||||
} else if (props.plan === WorkspacePlans.Pro) {
|
||||
return [
|
||||
{
|
||||
title: 'Unlimited projects and models',
|
||||
tooltip: 'You can purchase this in the next step'
|
||||
},
|
||||
{
|
||||
title: 'Extra data regions',
|
||||
fixedPrice: '$500 per region / month',
|
||||
tooltip: 'Available upon request'
|
||||
},
|
||||
{
|
||||
title: 'Priority support',
|
||||
fixedPrice: 'Contact us for pricing',
|
||||
tooltip: 'Available upon request'
|
||||
}
|
||||
]
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
name="includeArchived"
|
||||
:value="true"
|
||||
label="Include resolved"
|
||||
label-position="right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
title="Unlimited projects and models"
|
||||
:subtitle="`${addonPrice} per editor/month`"
|
||||
info="Power through with unlimited projects and models in your workspace."
|
||||
disclaimer="Only on Starter & Business plans"
|
||||
disclaimer="Only on Business plan"
|
||||
:button="unlimitedAddOnButton"
|
||||
/>
|
||||
|
||||
@@ -51,7 +51,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const {
|
||||
isPaidPlan,
|
||||
isBusinessPlan,
|
||||
currency,
|
||||
plan,
|
||||
intervalIsYearly,
|
||||
@@ -78,14 +78,14 @@ const addOnButtonTooltip = computed(() => {
|
||||
return 'You must be a workspace admin in order to purchase the add-on'
|
||||
if (hasUnlimitedAddon.value)
|
||||
return 'The add-on is already included in your subscription'
|
||||
if (!isPaidPlan.value) return 'Only available for Starter & Business plans'
|
||||
if (!isBusinessPlan.value) return 'Only available for the Business plan'
|
||||
return undefined
|
||||
})
|
||||
|
||||
const unlimitedAddOnButton = computed(() => ({
|
||||
text: 'Buy add-on',
|
||||
id: 'buy-add-on',
|
||||
disabled: !isPaidPlan.value || hasUnlimitedAddon.value || !isAdmin.value,
|
||||
disabled: !isBusinessPlan.value || hasUnlimitedAddon.value || !isAdmin.value,
|
||||
disabledMessage: addOnButtonTooltip.value,
|
||||
onClick: () => {
|
||||
isUpgradeDialogOpen.value = true
|
||||
|
||||
+7
-2
@@ -62,7 +62,7 @@ const mixpanel = useMixpanel()
|
||||
const { projectCount, modelCount } = useWorkspaceUsage(props.slug)
|
||||
const featureFlags = useFeatureFlags()
|
||||
|
||||
const showAddonSelect = ref<boolean>(true)
|
||||
const showAddonSelect = ref<boolean>(false)
|
||||
const isLoading = ref<boolean>(false)
|
||||
|
||||
const title = computed(() => {
|
||||
@@ -196,7 +196,12 @@ watch(
|
||||
() => isOpen.value,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
showAddonSelect.value = props.isChangingPlan && !isSamePlanWithAddon.value
|
||||
// Only show addon select for Business (Pro) plans
|
||||
const isBusinessPlan =
|
||||
props.plan === PaidWorkspacePlans.Pro ||
|
||||
props.plan === PaidWorkspacePlans.ProUnlimited
|
||||
showAddonSelect.value =
|
||||
props.isChangingPlan && !isSamePlanWithAddon.value && isBusinessPlan
|
||||
// If the add-on is required or already included, set it to yes
|
||||
if (usageExceedsNewPlanLimit.value && props.isChangingPlan) {
|
||||
includeUnlimitedAddon.value = 'yes'
|
||||
|
||||
@@ -250,6 +250,7 @@ const onReset = () => {
|
||||
}
|
||||
if (activePanel.value === ActivePanel.sectionBox) {
|
||||
resetSectionBoxCompletely()
|
||||
activePanel.value = ActivePanel.none
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
:name="`select-all-${selectedCount}-${totalCount}`"
|
||||
:model-value="areAllValuesSelected"
|
||||
:indeterminate="areSomeValuesSelected"
|
||||
class="pointer-events-none -mt-1"
|
||||
class="pointer-events-none"
|
||||
:class="selectAllCheckboxClasses"
|
||||
hide-label
|
||||
/>
|
||||
@@ -32,7 +32,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FormCheckbox } from '@speckle/ui-components'
|
||||
import { useFilterUtilities } from '~/lib/viewer/composables/filtering/filtering'
|
||||
import type { StringFilterData } from '~/lib/viewer/helpers/filters/types'
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<!-- eslint-disable vuejs-accessibility/click-events-have-key-events -->
|
||||
<!-- eslint-disable vuejs-accessibility/mouse-events-have-key-events -->
|
||||
<template>
|
||||
<div class="px-1">
|
||||
<div class="px-1 h-full">
|
||||
<div
|
||||
class="group/checkbox flex items-center justify-between gap-2 text-body-3xs py-0.5 px-2 hover:bg-highlight-1 rounded-md cursor-pointer"
|
||||
class="group/checkbox flex items-center justify-between gap-2 text-body-3xs py-0.5 px-2 hover:bg-highlight-1 rounded-md cursor-pointer h-full"
|
||||
@click="$emit('toggle')"
|
||||
@mouseenter="highlight"
|
||||
@mouseleave="unhighlight"
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="flex items-center min-w-0">
|
||||
<!-- Checkbox is purely visual - so pointer-events-none -->
|
||||
<FormCheckbox
|
||||
class="pointer-events-none -mt-1"
|
||||
class="pointer-events-none"
|
||||
:class="{
|
||||
'border-transparent group-hover/checkbox:border-outline-5': !isSelected,
|
||||
'opacity-50 dark:!bg-transparent !border dark:!border-outline-5 !group-hover/checkbox:border-outline-5':
|
||||
@@ -42,7 +42,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FormCheckbox } from '@speckle/ui-components'
|
||||
import { useFilterUtilities } from '~/lib/viewer/composables/filtering/filtering'
|
||||
import { getFilterValueCount } from '~/lib/viewer/helpers/filters/utils'
|
||||
import type { StringFilterData } from '~/lib/viewer/helpers/filters/types'
|
||||
|
||||
@@ -104,11 +104,6 @@ onResult((result) => {
|
||||
newState.plan === PaidWorkspacePlans.ProUnlimited
|
||||
) {
|
||||
goToStep(WizardSteps.Region)
|
||||
} else if (
|
||||
newState.plan === PaidWorkspacePlans.Team ||
|
||||
newState.plan === PaidWorkspacePlans.TeamUnlimited
|
||||
) {
|
||||
goToStep(WizardSteps.AddOns)
|
||||
} else {
|
||||
goToStep(WizardSteps.Pricing)
|
||||
}
|
||||
|
||||
@@ -92,15 +92,9 @@ export const useWorkspacesWizard = () => {
|
||||
let shouldComplete = false
|
||||
|
||||
if (wizardState.value.currentStep === WizardSteps.Pricing) {
|
||||
if (state.value.plan === WorkspacePlans.Free) {
|
||||
shouldComplete = true
|
||||
}
|
||||
}
|
||||
|
||||
if (wizardState.value.currentStep === WizardSteps.AddOns) {
|
||||
if (
|
||||
state.value.plan === WorkspacePlans.Team ||
|
||||
state.value.plan === WorkspacePlans.TeamUnlimited
|
||||
state.value.plan === WorkspacePlans.Free ||
|
||||
state.value.plan === WorkspacePlans.Team
|
||||
) {
|
||||
shouldComplete = true
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<template>
|
||||
<div
|
||||
class="relative flex"
|
||||
:class="labelPosition === 'left' ? 'flex-row-reverse items-center' : 'items-start'"
|
||||
class="relative flex items-center"
|
||||
:class="[
|
||||
labelPosition === 'left' && 'flex-row-reverse items-center',
|
||||
labelPosition === 'top' && 'items-start',
|
||||
labelPosition === 'right' && 'items-center'
|
||||
]"
|
||||
>
|
||||
<div
|
||||
class="flex items-center h-6"
|
||||
class="flex items-center h-3.5 w-3.5"
|
||||
:class="labelPosition === 'left' ? 'w-1/2 justify-end mr-2' : ''"
|
||||
>
|
||||
<div class="relative w-3.5 h-3.5">
|
||||
<div class="relative flex h-full w-full">
|
||||
<input
|
||||
:id="finalId"
|
||||
:checked="coreChecked"
|
||||
|
||||
@@ -4,7 +4,7 @@ import { clientOs, ModifierKeys } from '~~/src/helpers/form/input'
|
||||
import { computed, ref } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
export type LabelPosition = 'top' | 'left'
|
||||
export type LabelPosition = 'top' | 'left' | 'right'
|
||||
|
||||
/**
|
||||
* onKeyDown wrapper that also checks for modifier keys being pressed
|
||||
|
||||
@@ -58,7 +58,6 @@ import {
|
||||
ObjectLoader2Flags,
|
||||
ObjectLoader2Factory
|
||||
} from '@speckle/objectloader2'
|
||||
import { SectionCaps } from './Extensions/SectionCaps.ts/SectionCaps'
|
||||
import { MeasurementType } from '@speckle/shared/viewer/state'
|
||||
|
||||
export default class Sandbox {
|
||||
@@ -434,8 +433,6 @@ export default class Sandbox {
|
||||
}
|
||||
this.viewer.getExtension(SectionTool).setBox(box)
|
||||
this.viewer.getExtension(SectionTool).toggle()
|
||||
const sectionCaps = this.viewer.getExtension(SectionCaps)
|
||||
if (sectionCaps) sectionCaps.enabled = !sectionCaps.enabled
|
||||
})
|
||||
|
||||
const toggleSectionBoxVisibility = this.tabs.pages[0].addButton({
|
||||
|
||||
@@ -638,6 +638,9 @@ const getStream = () => {
|
||||
|
||||
// Revit v3 instances
|
||||
// 'https://app.speckle.systems/projects/03074a2834/models/a013d06fe1@cc11e1ead1'
|
||||
|
||||
// Gergo's new house
|
||||
// 'https://app.speckle.systems/projects/4743372784/models/2aeaa357e6'
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,11 @@ export class PerpendicularMeasurement extends Measurement {
|
||||
public toMeasurementData(): MeasurementData {
|
||||
const data = super.toMeasurementData()
|
||||
data.innerPoints = [[this.midPoint.x, this.midPoint.y, this.midPoint.z]]
|
||||
if (this.flipStartNormal) {
|
||||
vec3Buff0.copy(this.startNormal)
|
||||
vec3Buff0.negate()
|
||||
data.startNormal = [vec3Buff0.x, vec3Buff0.y, vec3Buff0.z]
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface InputEventPayload {
|
||||
//TO DO: Define proper interface for InputEvent data
|
||||
export default class Input extends EventEmitter {
|
||||
private static readonly MAX_DOUBLE_CLICK_TIMING = 500
|
||||
private static readonly MIN_CLICK_TIMING = 150
|
||||
private static readonly MIN_CLICK_TIMING = 200
|
||||
private tapTimeout: number = 0
|
||||
private lastTap = 0
|
||||
private lastClick = 0
|
||||
|
||||
Reference in New Issue
Block a user