Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(dui3): revit view send filter #3385

Merged
merged 10 commits into from
Oct 29, 2024
39 changes: 30 additions & 9 deletions packages/dui3/components/filter/ListSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,64 @@
<FormSelectBase
v-model="selectedFilterName"
name="sendFilter"
label="Avaialble send filters"
label="Selected filter"
class="w-full"
fixed-height
show-label
:items="filterNames"
:allow-unset="false"
mount-menu-on-body
>
<template #something-selected="{ value }">
<span class="text-primary text-base">{{ value }}</span>
<span class="text-primary text-base text-sm">{{ value }}</span>
</template>
<template #option="{ item }">
<span class="text-base">{{ item }}</span>
<span class="text-base text-sm">{{ item }}</span>
</template>
</FormSelectBase>
</div>
<div v-if="selectedFilter">
<div v-if="selectedFilter.name === 'Everything'">
<div
v-if="
selectedFilter.id === 'everything' || selectedFilter.name === 'Everything' // TODO: damn. remove name check later, if we remove now it will break production... we should differentiate its id and display name
"
>
<div class="p-4 text-primary bg-blue-500/10 rounded-md text-xs">
All supported objects will be sent. Depending on the model, this might take a
while.
</div>
</div>
<div v-else-if="selectedFilter.name === 'Selection'">
<div
v-else-if="
selectedFilter.id === 'selection' || selectedFilter.name === 'Selection' // TODO: damn. remove name check later, if we remove now it will break production... we should differentiate its id and display name
"
>
<FilterSelection
:filter="(selectedFilter as IDirectSelectionSendFilter)"
@update:filter="(filter : ISendFilter) => (selectedFilter = filter)"
/>
</div>
<div v-else-if="selectedFilter.name === 'Layers'">TODO</div>
<div v-else-if="selectedFilter.id === 'layers'">TODO</div>
<div v-else-if="selectedFilter.id === 'revitViews'">
<FilterRevitViews
:filter="(selectedFilter as RevitViewsSendFilter)"
@update:filter="(filter : ISendFilter) => (selectedFilter = filter)"
/>
</div>
</div>
<div v-if="!!filter" class="text-xs caption rounded p-2 bg-orange-500/10">
This action will replace the existing
<b>{{ filter.name }}</b>
<b>{{ selectedFilterName }}</b>
filter.
</div>
</div>
</template>
<script setup lang="ts">
import type { ISendFilter, IDirectSelectionSendFilter } from 'lib/models/card/send'
import type {
ISendFilter,
IDirectSelectionSendFilter,
RevitViewsSendFilter
} from 'lib/models/card/send'
import { useHostAppStore } from '~~/store/hostApp'
import { storeToRefs } from 'pinia'

Expand All @@ -56,7 +75,9 @@ const props = defineProps<{
const emit = defineEmits<{ (e: 'update:filter', value: ISendFilter): void }>()
const selectedFilter = ref<ISendFilter>(props.filter || selectionFilter.value)

const selectedFilterName = ref(selectionFilter.value.name)
const selectedFilterName = ref(
props.filter?.name || sendFilters.value?.find((f) => f.isDefault)?.name
)
const filterNames = computed(() => sendFilters.value?.map((f) => f.name))

watch(selectedFilterName, (newValue) => {
Expand Down
58 changes: 58 additions & 0 deletions packages/dui3/components/filter/revit/Views.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<div class="mt-4 space-y-2">
<FormSelectBase
key="name"
v-model="selectedView"
:search="true"
:search-placeholder="''"
:filter-predicate="searchFilterPredicate"
name="view"
label="View"
placeholder="Nothing selected"
class="w-full"
fixed-height
show-label
:items="store.availableViews"
:allow-unset="false"
mount-menu-on-body
>
<template #something-selected="{ value }">
<span class="text-primary text-base text-sm">{{ value }}</span>
</template>
<template #option="{ item }">
<span class="text-base text-sm">{{ item }}</span>
</template>
</FormSelectBase>
</div>
</template>

<script setup lang="ts">
import { useHostAppStore } from '~/store/hostApp'
import type { ISendFilter, RevitViewsSendFilter } from '~/lib/models/card/send'

const store = useHostAppStore()

const emit = defineEmits<{
(e: 'update:filter', filter: ISendFilter): void
}>()

const props = defineProps<{
filter: RevitViewsSendFilter
}>()

const selectedView = ref<string>(props.filter.selectedView)

const searchFilterPredicate = (item: string, search: string) =>
item.toLocaleLowerCase().includes(search.toLocaleLowerCase())

watch(
selectedView,
(newValue) => {
const filter = { ...props.filter } as RevitViewsSendFilter
filter.selectedView = newValue as string
filter.summary = newValue
emit('update:filter', filter)
},
{ deep: true, immediate: true }
)
</script>
6 changes: 6 additions & 0 deletions packages/dui3/lib/models/card/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ISenderModelCard extends IModelCard {
}

export interface ISendFilter extends IDiscriminatedObject {
id: string
name: string
summary: string
isDefault: boolean
Expand All @@ -19,6 +20,11 @@ export interface IDirectSelectionSendFilter extends ISendFilter {
selectedObjectIds: string[]
}

export interface RevitViewsSendFilter extends ISendFilter {
selectedView: string
availableViews: string[]
}

export class SenderModelCard extends ModelCard implements ISenderModelCard {
sendFilter?: ISendFilter | undefined
sending?: boolean | undefined
Expand Down
20 changes: 16 additions & 4 deletions packages/dui3/store/hostApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type { IReceiverModelCard } from '~/lib/models/card/receiver'
import type {
IDirectSelectionSendFilter,
ISendFilter,
ISenderModelCard
ISenderModelCard,
RevitViewsSendFilter
} from 'lib/models/card/send'
import type { ToastNotification } from '@speckle/ui-components'
import type { Nullable } from '@speckle/shared'
Expand Down Expand Up @@ -45,6 +46,8 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
const documentInfo = ref<DocumentInfo>()
const documentModelStore = ref<DocumentModelStore>({ models: [] })

const availableViews = ref<string[]>()

const dismissNotification = () => {
currentNotification.value = null
}
Expand Down Expand Up @@ -256,7 +259,8 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
// You should stop asking why if you saw anything related autocad..
// It solves the press "escape" issue.
// Because probably we don't give enough time to acad complete it's previos task and it stucks.
if (hostAppName.value === 'autocad') {
const shittyHostApps = ['autocad']
if (shittyHostApps.includes(hostAppName.value as string)) {
setTimeout(() => {
void app.$sendBinding.send(modelCardId)
}, 500) // I prefer to sacrifice 500ms
Expand Down Expand Up @@ -443,8 +447,15 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
/**
* Sources the available send filters from the app. This is useful in case of host app layer changes, etc.
*/
const refreshSendFilters = async () =>
(sendFilters.value = await app.$sendBinding?.getSendFilters())
const refreshSendFilters = async () => {
sendFilters.value = await app.$sendBinding?.getSendFilters()
const revitViews = sendFilters.value.find(
(f) => f.id === 'revitViews'
) as RevitViewsSendFilter
if (revitViews) {
availableViews.value = revitViews.availableViews
}
}

const getSendSettings = async () => {
sendSettings.value = await app.$sendBinding.getSendSettings()
Expand Down Expand Up @@ -549,6 +560,7 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
currentNotification,
showErrorDialog,
hostAppError,
availableViews,
setNotification,
setModelError,
setLatestAvailableVersion,
Expand Down