fix(dui): prevents invalidate selection filter across not just selection

This commit is contained in:
Björn Steinhagen
2026-02-25 11:01:30 +02:00
parent a37b3389d6
commit 35ddce1f90
3 changed files with 57 additions and 20 deletions
+3 -8
View File
@@ -119,7 +119,7 @@
</ModelCardBase>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ref, onMounted, computed } from 'vue'
import ModelCardBase from '~/components/model/CardBase.vue'
import { Square3Stack3DIcon } from '@heroicons/vue/20/solid'
import type { ModelCardNotification } from '~/lib/models/card/notification'
@@ -212,21 +212,16 @@ const sendOrCancel = () => {
}
const newFilter = ref<ISendFilter>()
const updateFilter = (filter: ISendFilter) => {
newFilter.value = filter
}
const isSaveDisabled = computed(() => {
const f = newFilter.value || props.modelCard.sendFilter
return (
f?.name === 'Selection' &&
(!f.selectedObjectIds || f.selectedObjectIds.length === 0)
)
return !store.validateSendFilter(newFilter.value || props.modelCard.sendFilter).valid
})
const saveFilter = async () => {
if (!newFilter.value) return
if (!newFilter.value) return // Safety check
void trackEvent('DUI3 Action', {
name: 'Publish Card Filter Change',
filter: newFilter.value.typeDiscriminator
+11 -11
View File
@@ -42,10 +42,7 @@
}
"
/>
<div
v-tippy="!canPublish && !isLoadingPermissions ? publishLimitMessage : ''"
class="mt-2"
>
<div v-tippy="publishTooltipMessage" class="mt-2">
<FormButton
full-width
:disabled="isPublishDisabled"
@@ -62,7 +59,6 @@
</CommonDialog>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useSubscription } from '@vue/apollo-composable'
import type {
@@ -108,15 +104,19 @@ const isLoadingPermissions = ref(false)
const hostAppStore = useHostAppStore()
const selectionStore = useSelectionStore()
const isSelectionEmpty = computed(() => {
const publishValidation = computed(() => hostAppStore.validateSendFilter(filter.value))
const isPublishDisabled = computed(() => {
return (
filter.value?.name === 'Selection' &&
(!selectionStore.selectionInfo.selectedObjectIds ||
selectionStore.selectionInfo.selectedObjectIds.length === 0)
!canPublish.value || isLoadingPermissions.value || !publishValidation.value.valid
)
})
const isPublishDisabled = computed(() => {
return !canPublish.value || isLoadingPermissions.value || isSelectionEmpty.value
const publishTooltipMessage = computed(() => {
if (!publishValidation.value.valid) return publishValidation.value.reason
if (!canPublish.value && !isLoadingPermissions.value)
return publishLimitMessage.value || ''
return ''
})
const updateSearchText = (text: string | undefined) => {
+43 -1
View File
@@ -11,6 +11,7 @@ import type {
ISendFilterSelectItem,
ISenderModelCard,
RevitViewsSendFilter,
RevitCategoriesSendFilter,
SendFilterSelect
} from '~/lib/models/card/send'
import type { ToastNotification } from '@speckle/ui-components'
@@ -22,6 +23,7 @@ import { defineStore } from 'pinia'
import type { CardSetting } from '~/lib/models/card/setting'
import type { DUIAccount } from '~/store/accounts'
import { useAccountStore } from '~/store/accounts'
import { useSelectionStore } from '~/store/selection'
import {
useUpdateConnector,
type Version
@@ -366,6 +368,45 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
*/
app.$sendBinding?.on('refreshSendFilters', () => void refreshSendFilters())
const validateSendFilter = (
filter?: ISendFilter
): { valid: boolean; reason?: string } => {
if (!filter) return { valid: false, reason: 'No filter selected' }
if (filter.name === 'Selection' || filter.id === 'selection') {
const selectionStore = useSelectionStore()
if (
!selectionStore.selectionInfo.selectedObjectIds ||
selectionStore.selectionInfo.selectedObjectIds.length === 0
) {
return { valid: false, reason: 'No objects selected to publish' }
}
}
if (filter.type === 'Select' || filter.id === 'navisworksSavedSets') {
const f = filter as SendFilterSelect
if (!f.selectedItems || f.selectedItems.length === 0) {
return { valid: false, reason: 'No items selected to publish' }
}
}
if (filter.id === 'revitCategories' || filter.id === 'archicadLayers') {
const f = filter as RevitCategoriesSendFilter
if (!f.selectedCategories || f.selectedCategories.length === 0) {
return { valid: false, reason: 'No categories selected to publish' }
}
}
if (filter.id === 'revitViews') {
const f = filter as RevitViewsSendFilter
if (!f.selectedView || f.selectedView.trim() === '') {
return { valid: false, reason: 'No view selected to publish' }
}
}
return { valid: true }
}
/**
* Send functionality
*/
@@ -924,6 +965,7 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
getSendSettings,
setModelSendResult,
setModelReceiveResult,
handleModelProgressEvents
handleModelProgressEvents,
validateSendFilter
}
})