Skip to content

Commit

Permalink
Merge pull request #4580 from FlowFuse/4562_replace-assetCompare-visi…
Browse files Browse the repository at this point in the history
…bility-selector-and-logs-dropdowns

Replace the AssetCompareDialog, VisibilitySelector and Logs dropdowns
  • Loading branch information
Steve-Mcl authored Oct 1, 2024
2 parents a1cc1c5 + 00197f4 commit f40f811
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 86 deletions.
48 changes: 35 additions & 13 deletions frontend/src/components/SectionTopMenu.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
<template>
<div class="ff-section-header flex flex-nowrap border-b border-gray-400 mb-4 sm:mb-2 text-gray-500 justify-between h-12">
<div class="flex">
<div class="w-full flex items-center md:w-auto mb-2 mr-8 gap-x-2">
<div class="w-full wrapper flex items-center md:w-auto mb-2 gap-x-2">
<div class="flex gap-2 items-center">
<slot name="hero">
<div class="flex">
<div class="text-gray-800 text-xl font-medium whitespace-nowrap">{{ hero }}</div>
</div>
</slot>
<InformationCircleIcon v-if="hasInfoDialog" class="min-w-[20px] ff-icon text-gray-800 cursor-pointer hover:text-blue-700" @click="openInfoDialog()" />
<span v-if="info" class="hidden sm:block text-gray-400">{{ info }}</span>
</div>
<ul v-if="options.length > 0" class="flex">
<li v-for="item in options" :key="item.name" class="mr-8 pt-1 flex">
<router-link :to="item.path" class="forge-nav-item" active-class="forge-nav-item-active" :data-nav="`section-${item.name.toLowerCase()}`">{{ item.name }}</router-link>
</li>
</ul>
<span v-if="info" class="hidden sm:block text-gray-400 info">{{ info }}</span>
<div class="actions">
<ul v-if="options.length > 0" class="flex">
<li v-for="item in options" :key="item.name" class="mr-8 pt-1 flex">
<router-link :to="item.path" class="forge-nav-item" active-class="forge-nav-item-active" :data-nav="`section-${item.name.toLowerCase()}`">{{ item.name }}</router-link>
</li>
</ul>
<ul v-if="hasTools" class="flex-shrink-0">
<li class="w-full md:w-auto flex-grow mb-2 text-right">
<slot name="tools" />
</li>
</ul>
</div>
</div>
<ul v-if="hasTools" class="flex-shrink-0">
<li class="w-full md:w-auto flex-grow mb-2 text-right">
<slot name="tools" />
</li>
</ul>
</div>
<ff-dialog v-if="hasInfoDialog" ref="help-dialog" class="ff-dialog-box--info" :header="helpHeader || 'FlowFuse Info'">
<template #default>
Expand Down Expand Up @@ -82,3 +84,23 @@ export default {
}
</script>

<style lang="scss">
.wrapper {
flex: 1;
align-items: baseline;
overflow: hidden;
.info {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.actions {
display: flex;
flex: 1;
justify-content: flex-end;
}
}
</style>
16 changes: 8 additions & 8 deletions frontend/src/components/dialogs/AssetCompareDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
>
<template #default>
<div class="flex gap-2" data-el="snapshot-compare-toolbar">
<ff-dropdown v-model="compareSnapshot" class="flex-grow">
<ff-dropdown-option
v-for="option in compareSnapshotList" :key="option.value" :value="option.value"
:label="option.label" :title="option.description" class="text-sm"
>
{{ option.label }}
</ff-dropdown-option>
</ff-dropdown>
<ff-listbox
v-model="compareSnapshot"
:options="compareSnapshotList"
data-el="snapshots-list"
label-key="label"
option-title-key="description"
class="flex-grow"
/>
<ff-button
v-if="true"
:disabled="!compareSnapshot"
Expand Down
50 changes: 36 additions & 14 deletions frontend/src/components/file-browser/VisibilitySelector.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
<template>
<ff-dropdown :disabled="isDisabled" data-el="visibility-selector" class="visibility-selector">
<template #placeholder>
<ff-listbox :disabled="isDisabled" data-el="visibility-selector" class="ff-dropdown visibility-selector">
<template #button>
<div v-if="isCurrentFolderPublic" class="flex gap-2"><GlobeAltIcon class="ff-icon" /> Public</div>
<div v-else class="flex gap-2"><ProjectIcon class="ff-icon" /> Node-RED Only</div>
</template>
<template #default>
<ff-dropdown-option data-action="select-private" :disabled="!isCurrentFolderPublic" @click="selected('private')">
<div class="flex gap-2"><ProjectIcon class="ff-icon" /> Node-RED Only</div>
</ff-dropdown-option>
<ff-dropdown-option data-action="select-public" @click="showStaticPathSelectionDialog">
<div class="flex gap-2"><GlobeAltIcon class="ff-icon" /> Public</div>
</ff-dropdown-option>
<template #options>
<ListboxOption
class="ff-option"
:class="[!isCurrentFolderPublic ? 'cursor-not-allowed bg-gray-200 text-gray-500' : '']"
:disabled="!isCurrentFolderPublic"
data-action="select-private"
@click="selected('private')"
>
<li>
<div class="ff-option-content">
<div class="flex gap-2"><ProjectIcon class="ff-icon" /> Node-RED Only</div>
</div>
</li>
</ListboxOption>
<ListboxOption class="ff-option" data-action="select-public" @click="showStaticPathSelectionDialog">
<li>
<div class="ff-option-content">
<div class="flex gap-2"><GlobeAltIcon class="ff-icon" /> Public</div>
</div>
</li>
</ListboxOption>
</template>
</ff-dropdown>
</ff-listbox>
<ff-dialog
ref="selectStaticPath" data-el="select-static-path-dialog"
header="Select a static path"
Expand All @@ -39,15 +53,22 @@
</template>

<script>
import { ListboxOption } from '@headlessui/vue'
import { GlobeAltIcon } from '@heroicons/vue/outline'
import ProjectIcon from '../../components/icons/Projects.js'
import { removeSlashes } from '../../composables/String.js'
import Alerts from '../../services/alerts.js'
import FfListbox from '../../ui-components/components/form/ListBox.vue'
export default {
name: 'VisibilitySelector',
components: { ProjectIcon, GlobeAltIcon },
components: {
ListboxOption,
FfListbox,
ProjectIcon,
GlobeAltIcon
},
inheritAttrs: false,
props: {
breadcrumbs: {
Expand Down Expand Up @@ -137,16 +158,17 @@ export default {
.ff-dropdown.visibility-selector {
min-width: 130px;
.ff-dropdown-selected {
.ff-button {
padding-left: 0;
padding-right: 0;
border: none;
background: none !important;
}
.ff-dropdown-options {
.ff-options {
border: 1px solid $ff-grey-200 !important;
.ff-dropdown-option {
.ff-option {
background: white !important;
border: none !important;
Expand Down
14 changes: 8 additions & 6 deletions frontend/src/pages/application/Logs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
<template #tools>
<div style="display: flex;align-items: center;">
<div class="mr-2"><strong>Instance:</strong></div>
<ff-dropdown ref="dropdown" v-model="input.instanceId" class="w-full">
<ff-dropdown-option
v-for="inputInstance in instances" :key="inputInstance.id"
:label="inputInstance.name" :value="inputInstance.id"
/>
</ff-dropdown>
<ff-listbox
ref="dropdown"
v-model="input.instanceId"
:options="instances"
label-key="name"
value-key="id"
class="w-full"
/>
<router-link v-if="instance?.meta" :to="{ name: 'Instance', params: { id: instance.id }}">
<InstanceStatusBadge :status="instance.meta?.state" :pendingStateChange="instance?.pendingStateChange" :optimisticStateChange="instance.optimisticStateChange" class="ml-2" />
</router-link>
Expand Down
59 changes: 37 additions & 22 deletions frontend/src/ui-components/components/form/ListBox.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<template>
<Listbox v-model="value" :disabled="disabled" class="ff-listbox">
<div class="relative">
<ListboxButton class="w-full rounded-md bg-white flex justify-between button">
<span class="block truncate">{{ selectedLabel }}</span>
<ListboxButton
class="w-full rounded-md bg-white flex justify-between ff-button"
:class="[disabled ? 'cursor-not-allowed bg-gray-200 text-gray-500' : '']"
>
<slot name="button">
<span class="block truncate">{{ selectedLabel }}</span>
</slot>
<span class="icon pointer-events-none inset-y-0 flex items-center pl-2">
<ChevronDownIcon class="h-5 w-5 text-black" aria-hidden="true" />
<ChevronDownIcon :class="['h-5 w-5', disabled ? 'text-gray-500' : 'text-black']" aria-hidden="true" />
</span>
</ListboxButton>

Expand All @@ -13,21 +18,24 @@
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<ListboxOptions class="absolute w-full overflow-auto bg-white py-1 options">
<ListboxOption
v-for="option in options"
v-slot="{ active, selected }"
:key="labelKey === 'label' ? option.label : option[labelKey]"
:value="option"
as="template"
class="option"
>
<li>
<div class="option-content" :class="{selected, active}">
{{ labelKey === 'label' ? option.label : option[labelKey] }}
</div>
</li>
</ListboxOption>
<ListboxOptions class="absolute w-full overflow-auto bg-white py-1 ff-options">
<slot name="options">
<ListboxOption
v-for="option in options"
v-slot="{ active, selected }"
:key="labelKey === 'label' ? option.label : option[labelKey]"
:value="option"
as="template"
class="ff-option"
:title="optionTitleKey ? option[optionTitleKey] : null"
>
<li>
<div class="ff-option-content" :class="{selected, active}">
{{ labelKey === 'label' ? option.label : option[labelKey] }}
</div>
</li>
</ListboxOption>
</slot>
</ListboxOptions>
</transition>
</div>
Expand Down Expand Up @@ -83,6 +91,11 @@ export default {
default: 'value',
type: String
},
optionTitleKey: {
required: false,
default: null,
type: [null, String]
},
returnModel: {
required: false,
default: false,
Expand Down Expand Up @@ -123,13 +136,15 @@ export default {
<style lang="scss">
.ff-listbox {
display: inline-block;
min-width: 200px;
&:focus-visible {
border: none;
outline: none;
}
.button {
.ff-button {
border: 1px solid $ff-grey-300;
padding: 5px 5px 5px 10px;
&:focus-visible, &:focus {
Expand All @@ -144,7 +159,7 @@ export default {
}
}
.options {
.ff-options {
background: $ff-grey-50;
box-shadow: 0 6px 9px 0 #00000038;
max-height: 14rem;
Expand All @@ -158,7 +173,7 @@ export default {
outline: none;
}
.option {
.ff-option {
border-bottom: 1px solid $ff-grey-200;
background-color: $ff-grey-50;
cursor: pointer;
Expand All @@ -167,7 +182,7 @@ export default {
border-bottom: none;
}
.option-content {
.ff-option-content {
padding: $ff-unit-sm $ff-unit-md;
&.selected, &.active {
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/ui-components/stylesheets/ff-components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
line-height: 20px;
height: 32px;
position: relative;

justify-content: center;
font-weight: bold;
height: auto;
Expand All @@ -94,7 +94,7 @@
line-height: 16px;
height: 24px;
}

&.ff-btn-fwidth {
justify-content: center;
}
Expand Down Expand Up @@ -410,7 +410,7 @@ li.ff-list-item {
border-radius: 4px;
background-color: transparent;
border: 1px solid;
border-color: $ff-grey-400;
border-color: $ff-grey-400;
}
&:hover:not([disabled=true]) {
.checkbox {
Expand Down Expand Up @@ -573,7 +573,7 @@ li.ff-list-item {
border-radius: 4px;
background-color: transparent;
border: 1px solid $ff-grey-400;
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")
}
}

Expand Down Expand Up @@ -676,7 +676,7 @@ li.ff-list-item {
}

/*
FF Data Table
FF Data Table
*/
.ff-data-table {
width: 100%;
Expand Down Expand Up @@ -1190,4 +1190,4 @@ $countdown_size: 20px;
-webkit-transform: rotate(360deg);
}
}
}
}
4 changes: 2 additions & 2 deletions test/e2e/frontend/cypress/tests-ee/devices/snapshots.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ describe('FlowForge - Devices - With Billing', () => {
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"] [data-action="compare-snapshots"]').should('be.disabled')

// select the snapshot to compare with
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"] .ff-dropdown[disabled=false]').click()
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"] .ff-dropdown-options > .ff-dropdown-option:first').click()
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"]').click()
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"] .ff-options > .ff-option:first').click()
// click compare button
cy.get('[data-el="dialog-compare-snapshot"] [data-el="snapshot-compare-toolbar"] [data-action="compare-snapshots"]').click()
cy.wait('@fullSnapshot')
Expand Down
Loading

0 comments on commit f40f811

Please sign in to comment.