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(web-core,lite,xo6): add useDisabled composable and replace DisabledContext usage #8133

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions @xen-orchestra/lite/src/components/RouterTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@

<script lang="ts" setup>
import TabItem from '@core/components/tab/TabItem.vue'
import { useContext } from '@core/composables/context.composable'
import { DisabledContext } from '@core/context'
import { useDisabled } from '@core/composables/disabled.composable'
import type { RouteLocationRaw } from 'vue-router'
const props = withDefaults(
defineProps<{
to: RouteLocationRaw
disabled?: boolean
}>(),
{ disabled: undefined }
)
const props = defineProps<{
to: RouteLocationRaw
disabled?: boolean
}>()
const isDisabled = useContext(DisabledContext, () => props.disabled)
const isDisabled = useDisabled(() => props.disabled)
</script>
18 changes: 7 additions & 11 deletions @xen-orchestra/lite/src/components/form/FormCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,19 @@

<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { useContext } from '@/composables/context.composable'
import { DisabledContext } from '@/context'
import { IK_CHECKBOX_TYPE, IK_FORM_HAS_LABEL } from '@/types/injection-keys'
import { useDisabled } from '@core/composables/disabled.composable'
import { faCheck, faCircle, faMinus } from '@fortawesome/free-solid-svg-icons'
import { useVModel } from '@vueuse/core'
import { computed, type HTMLAttributes, inject, useAttrs } from 'vue'
defineOptions({ inheritAttrs: false })
const props = withDefaults(
defineProps<{
modelValue?: unknown
disabled?: boolean
wrapperAttrs?: HTMLAttributes
}>(),
{ disabled: undefined }
)
const props = defineProps<{
modelValue?: unknown
disabled?: boolean
wrapperAttrs?: HTMLAttributes
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
Expand All @@ -46,7 +42,7 @@ const hasLabel = inject(
IK_FORM_HAS_LABEL,
computed(() => false)
)
const isDisabled = useContext(DisabledContext, () => props.disabled)
const isDisabled = useDisabled(() => props.disabled)
const icon = computed(() => {
if (type !== 'checkbox') {
return faCircle
Expand Down
34 changes: 16 additions & 18 deletions @xen-orchestra/lite/src/components/form/FormInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,32 +53,30 @@
<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { useContext } from '@/composables/context.composable'
import { ColorContext, DisabledContext } from '@/context'
import { ColorContext } from '@/context'
import type { Color } from '@/types'
import { IK_INPUT_ID, IK_INPUT_TYPE } from '@/types/injection-keys'
import { useDisabled } from '@core/composables/disabled.composable'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { faAngleDown } from '@fortawesome/free-solid-svg-icons'
import { useTextareaAutosize, useVModel } from '@vueuse/core'
import { computed, type HTMLAttributes, inject, nextTick, ref, useAttrs, watch } from 'vue'
defineOptions({ inheritAttrs: false })
const props = withDefaults(
defineProps<{
id?: string
modelValue?: any
color?: Color
before?: IconDefinition | string
after?: IconDefinition | string
beforeWidth?: string
afterWidth?: string
disabled?: boolean
required?: boolean
right?: boolean
wrapperAttrs?: HTMLAttributes
}>(),
{ disabled: undefined }
)
const props = defineProps<{
id?: string
modelValue?: any
color?: Color
before?: IconDefinition | string
after?: IconDefinition | string
beforeWidth?: string
afterWidth?: string
disabled?: boolean
required?: boolean
right?: boolean
wrapperAttrs?: HTMLAttributes
}>()
const emit = defineEmits<{
'update:modelValue': [value: any]
Expand All @@ -94,7 +92,7 @@ const value = useVModel(props, 'modelValue', emit)
const isEmpty = computed(() => props.modelValue == null || String(props.modelValue).trim() === '')
const inputType = inject(IK_INPUT_TYPE, 'input')
const isDisabled = useContext(DisabledContext, () => props.disabled)
const isDisabled = useDisabled(() => props.disabled)
const wrapperClass = computed(() => [
`form-${inputType}`,
Expand Down
30 changes: 14 additions & 16 deletions @xen-orchestra/lite/src/components/form/FormInputWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,26 @@
<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { useContext } from '@/composables/context.composable'
import { ColorContext, DisabledContext } from '@/context'
import { ColorContext } from '@/context'
import type { Color } from '@/types'
import { IK_FORM_HAS_LABEL, IK_INPUT_ID } from '@/types/injection-keys'
import { useDisabled } from '@core/composables/disabled.composable'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons'
import { uniqueId } from 'lodash-es'
import { computed, provide, useSlots } from 'vue'
const props = withDefaults(
defineProps<{
label?: string
id?: string
icon?: IconDefinition
learnMoreUrl?: string
warning?: string
error?: string
help?: string
disabled?: boolean
light?: boolean
}>(),
{ disabled: undefined }
)
const props = defineProps<{
label?: string
id?: string
icon?: IconDefinition
learnMoreUrl?: string
warning?: string
error?: string
help?: string
disabled?: boolean
light?: boolean
}>()
const slots = useSlots()
Expand All @@ -82,7 +80,7 @@ provide(
)
useContext(ColorContext, color)
useContext(DisabledContext, () => props.disabled)
useDisabled(() => props.disabled)
</script>

<style lang="postcss" scoped>
Expand Down
20 changes: 8 additions & 12 deletions @xen-orchestra/lite/src/components/ui/UiActionButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@

<script lang="ts" setup>
import UiIcon from '@/components/ui/icon/UiIcon.vue'
import { useContext } from '@/composables/context.composable'
import { DisabledContext } from '@/context'
import { useDisabled } from '@core/composables/disabled.composable'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
const props = withDefaults(
defineProps<{
busy?: boolean
disabled?: boolean
icon?: IconDefinition
active?: boolean
}>(),
{ disabled: undefined }
)
const props = defineProps<{
busy?: boolean
disabled?: boolean
icon?: IconDefinition
active?: boolean
}>()
const isDisabled = useContext(DisabledContext, () => props.disabled)
const isDisabled = useDisabled(() => props.disabled)
</script>

<style lang="postcss" scoped>
Expand Down
5 changes: 3 additions & 2 deletions @xen-orchestra/lite/src/components/ui/modals/UiModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

<script lang="ts" setup>
import { useContext } from '@/composables/context.composable'
import { ColorContext, DisabledContext } from '@/context'
import { ColorContext } from '@/context'
import type { Color } from '@/types'
import { IK_MODAL } from '@/types/injection-keys'
import { useDisabled } from '@core/composables/disabled.composable'
import { useMagicKeys, whenever } from '@vueuse/core'
import { inject, useAttrs } from 'vue'
Expand All @@ -28,7 +29,7 @@ const attrs = useAttrs()
const modal = inject(IK_MODAL)!
useContext(ColorContext, () => props.color)
useContext(DisabledContext, () => props.disabled || modal.isBusy)
useDisabled(() => props.disabled || modal.isBusy)
const { escape } = useMagicKeys()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@
</template>

<script lang="ts" setup>
import { useContext } from '@/composables/context.composable'
import { useModal } from '@/composables/modal.composable'
import { DisabledContext } from '@/context'
import { areSomeVmOperationAllowed } from '@/libs/vm'
import { VM_OPERATION } from '@/libs/xen-api/xen-api.enums'
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useVmStore } from '@/stores/xen-api/vm.store'
import MenuItem from '@core/components/menu/MenuItem.vue'
import { useDisabled } from '@core/composables/disabled.composable'
import { vTooltip } from '@core/directives/tooltip.directive'
import { faDisplay } from '@fortawesome/free-solid-svg-icons'
import { computed } from 'vue'
Expand All @@ -31,13 +30,11 @@ const props = defineProps<{
const { getByOpaqueRefs } = useVmStore().subscribe()
const isParentDisabled = useContext(DisabledContext)
const isSomeExportable = computed(() =>
getByOpaqueRefs(props.vmRefs).some(vm => areSomeVmOperationAllowed(vm, VM_OPERATION.EXPORT))
)
const isDisabled = computed(() => isParentDisabled.value || !isSomeExportable.value)
const isDisabled = useDisabled(() => !isSomeExportable.value)
const openModal = () => {
useModal(() => import('@/components/modals/VmExportModal.vue'), {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
$t(isSingleAction ? 'this-vm-cant-be-migrated' : 'no-selected-vm-can-be-migrated')
"
:busy="isMigrating"
:disabled="isParentDisabled || !isMigratable"
:disabled="isDisabled"
:icon="faRoute"
@click="openModal()"
>
Expand All @@ -15,14 +15,13 @@
</template>

<script lang="ts" setup>
import { useContext } from '@/composables/context.composable'
import { useModal } from '@/composables/modal.composable'
import { DisabledContext } from '@/context'
import { areSomeVmOperationAllowed, isVmOperationPending } from '@/libs/vm'
import { VM_OPERATION } from '@/libs/xen-api/xen-api.enums'
import type { XenApiVm } from '@/libs/xen-api/xen-api.types'
import { useVmStore } from '@/stores/xen-api/vm.store'
import MenuItem from '@core/components/menu/MenuItem.vue'
import { useDisabled } from '@core/composables/disabled.composable'
import { vTooltip } from '@core/directives/tooltip.directive'
import { faRoute } from '@fortawesome/free-solid-svg-icons'
import { computed } from 'vue'
Expand All @@ -34,8 +33,6 @@ const props = defineProps<{
const { getByOpaqueRefs } = useVmStore().subscribe()
const isParentDisabled = useContext(DisabledContext)
const isMigratable = computed(() =>
getByOpaqueRefs(props.selectedRefs).some(vm =>
areSomeVmOperationAllowed(vm, [VM_OPERATION.POOL_MIGRATE, VM_OPERATION.MIGRATE_SEND])
Expand All @@ -48,6 +45,8 @@ const isMigrating = computed(() =>
)
)
const isDisabled = useDisabled(() => !isMigratable.value)
const openModal = () =>
useModal(() => import('@/components/modals/VmMigrateModal.vue'), {
vmRefs: props.selectedRefs,
Expand Down
2 changes: 0 additions & 2 deletions @xen-orchestra/lite/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { createContext } from '@/composables/context.composable'
import type { Color } from '@/types'
import { computed } from 'vue'

export const DisabledContext = createContext(false)

export const ColorContext = createContext('info' as Color, color => ({
name: color,
textClass: computed(() => `context-color-${color.value}`),
Expand Down
20 changes: 8 additions & 12 deletions @xen-orchestra/web-core/lib/components/menu/MenuItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,24 @@
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import MenuList from '@core/components/menu/MenuList.vue'
import MenuTrigger from '@core/components/menu/MenuTrigger.vue'
import { useContext } from '@core/composables/context.composable'
import { DisabledContext } from '@core/context'
import { useDisabled } from '@core/composables/disabled.composable'
import { IK_CLOSE_MENU, IK_MENU_HORIZONTAL } from '@core/utils/injection-keys.util'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { faAngleDown, faAngleRight } from '@fortawesome/free-solid-svg-icons'
import { computed, inject, ref } from 'vue'

const props = withDefaults(
defineProps<{
icon?: IconDefinition
onClick?: () => any
disabled?: boolean
busy?: boolean
}>(),
{ disabled: undefined }
)
const props = defineProps<{
icon?: IconDefinition
onClick?: () => any
disabled?: boolean
busy?: boolean
}>()

const isParentHorizontal = inject(
IK_MENU_HORIZONTAL,
computed(() => false)
)
const isDisabled = useContext(DisabledContext, () => props.disabled)
const isDisabled = useDisabled(() => props.disabled)

const submenuIcon = computed(() => (isParentHorizontal.value ? faAngleDown : faAngleRight))

Expand Down
20 changes: 8 additions & 12 deletions @xen-orchestra/web-core/lib/components/menu/MenuList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
</template>

<script lang="ts" setup>
import { useContext } from '@core/composables/context.composable'
import { DisabledContext } from '@core/context'
import { useDisabled } from '@core/composables/disabled.composable'
import { IK_CLOSE_MENU, IK_MENU_HORIZONTAL, IK_MENU_TELEPORTED } from '@core/utils/injection-keys.util'
import { onClickOutside, unrefElement, whenever } from '@vueuse/core'
import placementJs, { type Options } from 'placement.js'
Expand All @@ -20,15 +19,12 @@ defineOptions({
inheritAttrs: false,
})

const props = withDefaults(
defineProps<{
horizontal?: boolean
border?: boolean
disabled?: boolean
placement?: Options['placement']
}>(),
{ disabled: undefined }
)
const props = defineProps<{
horizontal?: boolean
border?: boolean
disabled?: boolean
placement?: Options['placement']
}>()

const slots = useSlots()
const isOpen = ref(false)
Expand All @@ -42,7 +38,7 @@ provide(
computed(() => props.horizontal ?? false)
)

useContext(DisabledContext, () => props.disabled)
useDisabled(() => props.disabled)

let clearClickOutsideEvent: (() => void) | undefined

Expand Down
Loading
Loading