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

Show in the edit-menu the mini-widgets that are out of the top/bottom bar #1559

Merged
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
89 changes: 87 additions & 2 deletions src/components/EditMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,63 @@
</div>
</template>
</ExpansiblePanel>
<ExpansiblePanel
v-for="miniWidgetContainer in miniWidgetsBars"
:key="miniWidgetContainer.name"
:compact="interfaceStore.isLg || interfaceStore.isOnSmallScreen ? true : false"
invert-chevron
hover-effect
elevation-effect
no-top-divider
:is-expanded="miniWidgetContainer?.widgets!.length > 0"
>
<template #title>
<div
class="flex w-[90%] justify-between items-center 2xl:text-[18px] xl:text-[16px] lg:text-[14px] -mb-3 font-normal ml-2"
>
{{ miniWidgetContainer.name }}
<v-badge
:content="miniWidgetContainer.widgets?.length"
color="#4FA483"
rounded="md"
class="ml-10 2xl:mb-1 opacity-90"
:class="interfaceStore.isLg || interfaceStore.isOnSmallScreen ? 'scale-75' : ''"
/>
</div>
</template>
<template #content>
<div class="w-full mb-1">
<div class="flex flex-col items-center w-full 2xl:px-3 overflow-x-hidden grow">
<TransitionGroup name="fade">
<div v-if="miniWidgetContainer?.widgets?.isEmpty()" class="flex items-center justify-between w-full">
---
</div>
<div
v-for="widget in miniWidgetContainer.widgets"
:key="widget.hash"
class="flex items-center justify-center w-full border-[1px] border-[#FFFFFF15] rounded-md 2xl:mx-2 my-[3px] 2xl:p-1 pl-1 pr-[2px] py-[2px] cursor-pointer"
:class="store.miniWidgetManagerVars(widget.hash).highlighted ? 'bg-[#CBCBCB64]' : 'bg-[#CBCBCB2A]'"
@mouseover="store.miniWidgetManagerVars(widget.hash).highlighted = true"
@mouseleave="store.miniWidgetManagerVars(widget.hash).highlighted = false"
>
<div class="flex items-center justify-start w-full overflow-auto">
<p class="overflow-hidden select-none text-ellipsis whitespace-nowrap 2xl:text-sm text-xs ml-3">
{{ widget.name || widget.component }}
</p>
</div>
<v-divider vertical class="opacity-10 mr-1" />
<div
class="icon-btn mdi mdi-cog"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot the new enable/disable cog logic here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

:class="{ 'opacity-20 cursor-not-allowed': !isMiniWidgetConfigurable[widget.component as WidgetType] }"
@click="store.miniWidgetManagerVars(widget.hash).configMenuOpen = true"
/>
<div class="icon-btn mdi mdi-trash-can" @click="store.deleteMiniWidget(widget)" />
</div>
</TransitionGroup>
</div>
</div>
</template>
</ExpansiblePanel>
</div>
</div>
<div class="flex items-center justify-between edit-panel bottom-panel" :class="{ active: editMode }">
Expand Down Expand Up @@ -666,11 +723,13 @@ import {
type Profile,
type View,
type Widget,
CustomWidgetElementContainer,
CustomWidgetElementType,
ExternalWidgetSetupInfo,
InternalWidgetSetupInfo,
isMiniWidgetConfigurable,
isWidgetConfigurable,
MiniWidgetContainer,
MiniWidgetType,
WidgetType,
} from '@/types/widgets'
Expand All @@ -686,6 +745,32 @@ const { showDialog, closeDialog } = useInteractionDialog()
const interfaceStore = useAppInterfaceStore()
const store = useWidgetManagerStore()

const miniWidgetsBars = computed(() => {
let regularContainers = store.miniWidgetContainersInCurrentView.filter(
(container) => !container.name.startsWith('Top') && !container.name.startsWith('Bottom')
)
let customContainers = getAllMiniWidgetFromCustomWidget()
return [...regularContainers, ...customContainers]
})

const getAllMiniWidgetFromCustomWidget = (): MiniWidgetContainer[] => {
const allCustomBases = store.currentProfile.views
.flatMap((view) => view.widgets)
.filter((widget) => widget.component === WidgetType.CustomWidgetBase)

return allCustomBases.map((base) => {
const baseName = base.name || 'Unnamed Custom Widget'
const miniWidgets = base.options.elementContainers.flatMap(
(container: CustomWidgetElementContainer) => container.elements
)

return {
name: baseName,
widgets: miniWidgets,
}
})
}

const trashList = ref<Widget[]>([])
watch(trashList, () => {
nextTick(() => (trashList.value = []))
Expand Down Expand Up @@ -721,9 +806,9 @@ const emit = defineEmits<{
}>()

watch(
() => store.elementToShowOnDrawer?.hash,
() => store.elementToShowOnDrawer,
(newValue) => {
if (newValue) interfaceStore.configPanelVisible = true
if (newValue?.isCustomElement) interfaceStore.configPanelVisible = true
if (!newValue) interfaceStore.configPanelVisible = false
}
)
Expand Down
2 changes: 2 additions & 0 deletions src/components/widgets/CustomWidgetBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ const widgetAdded = (e: SortableEvent.SortableEvent, containerName: string): voi
if (newWidget && e.pullMode === 'clone') {
newWidget.hash = uuid()
widgetStore.miniWidgetManagerVars(newWidget.hash).configMenuOpen = true
lastKnownHashes.value.set(containerName, currentHashes)
return
}
widgetStore.showElementPropsDrawer(newWidget.hash)
lastKnownHashes.value.set(containerName, currentHashes)
Expand Down
37 changes: 28 additions & 9 deletions src/stores/widgetManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const useWidgetManagerStore = defineStore('widget-manager', () => {
const elementToShowOnDrawer = ref<CustomWidgetElement>()
const widgetToEdit = ref<Widget>()
const miniWidgetLastValues = useBlueOsStorage<Record<string, any>>('cockpit-mini-widget-last-values', {})
const floatingWidgetContainers = ref<MiniWidgetContainer[]>([])

const editWidgetByHash = (hash: string): Widget | undefined => {
widgetToEdit.value = currentProfile.value.views
Expand Down Expand Up @@ -272,11 +273,11 @@ export const useWidgetManagerStore = defineStore('widget-manager', () => {
const miniWidgetContainersInCurrentView = computed(() => {
const fixedBarContainers = currentMiniWidgetsProfile.value.containers
const viewBarContainers = currentView.value.miniWidgetContainers
const floatingWidgetContainers = currentView.value.widgets
floatingWidgetContainers.value = currentView.value.widgets
.filter((w) => w.component === WidgetType.MiniWidgetsBar)
.filter((w) => w.options && w.options.miniWidgetsContainer)
.map((w) => w.options.miniWidgetsContainer)
return [...fixedBarContainers, ...viewBarContainers, ...floatingWidgetContainers]
return [...fixedBarContainers, ...viewBarContainers, ...floatingWidgetContainers.value]
Comment on lines -275 to +280
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those line changes do not seen to have any effect in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

floatingWidgetContainers variable declaration was moved outside the const miniWidgetContainersInCurrentView computed variable.

This was changed so it will be possible to access the value from floatingWidgetContainers outside the scope of this function.
Check the change on line 649

})

/**
Expand Down Expand Up @@ -608,18 +609,34 @@ export const useWidgetManagerStore = defineStore('widget-manager', () => {
const container: MiniWidgetContainer | undefined = miniWidgetContainersInCurrentView.value.find((cont) => {
return cont.widgets.includes(miniWidget)
})
if (container === undefined) {
showDialog({ variant: 'error', message: 'Mini-widget container not found.' })
const customWidgetContainer = getElementByHash(miniWidget.hash)
if (container) {
const index = container.widgets.indexOf(miniWidget)
container.widgets.splice(index, 1)
// Remove miniWidget variable from the list of currently logged variables
CurrentlyLoggedVariables.removeVariable(miniWidget.options.displayName)
return
}
if (customWidgetContainer) {
removeElementFromCustomWidget(miniWidget.hash)
CurrentlyLoggedVariables.removeVariable(miniWidget.options.displayName)
return
}

const index = container.widgets.indexOf(miniWidget)
container.widgets.splice(index, 1)

// Remove miniWidget variable from the list of currently logged variables
CurrentlyLoggedVariables.removeVariable(miniWidget.options.displayName)
showDialog({ variant: 'error', message: 'Mini-widget container not found.' })
}

const customWidgetContainers = computed<MiniWidgetContainer[]>(() =>
currentProfile.value.views
.flatMap((view) => view.widgets)
.filter((widget) => widget.component === WidgetType.CustomWidgetBase)
.flatMap((widget) => widget.options.elementContainers)
.map((container) => ({
name: '',
widgets: container.elements as unknown as MiniWidget[],
}))
)

/**
* States whether the given mini-widget is a real mini-widget
* Fake mini-widgets are those used as placeholders, in the edit-menu, for example
Expand All @@ -630,6 +647,8 @@ export const useWidgetManagerStore = defineStore('widget-manager', () => {
const allContainers = [
...savedProfiles.value.flatMap((profile) => profile.views.flatMap((view) => view.miniWidgetContainers)),
...currentMiniWidgetsProfile.value.containers,
...floatingWidgetContainers.value,
...customWidgetContainers.value,
]

return allContainers.some((container) => container.widgets.some((widget) => widget.hash === miniWidgetHash))
Expand Down
Loading