filtering apps with user groups, added clear button in pickerdropdown component

This commit is contained in:
NEOLPAR 2022-07-11 15:12:45 +01:00
parent 2399dbceb9
commit d6483e8d92
4 changed files with 177 additions and 77 deletions

View File

@ -10,6 +10,7 @@
import Detail from "../../Typography/Detail.svelte"
export let primaryLabel = ""
export let primaryValue = null
export let id = null
export let placeholder = "Choose an option or type"
export let disabled = false
@ -73,6 +74,11 @@
primaryOpen = false
}
const onClearPrimary = () => {
dispatch("pickprimary", null)
primaryOpen = false
}
const onPickSecondary = newValue => {
dispatch("picksecondary", newValue)
secondaryOpen = false
@ -123,7 +129,7 @@
class:is-invalid={!!error}
class:is-disabled={disabled}
class:is-focused={focus}
style="width: 70%"
class:is-full-width={!secondaryOptions.length}
>
{#if iconData}
<svg
@ -153,6 +159,21 @@
class="spectrum-Textfield-input spectrum-InputGroup-input"
class:labelPadding={iconData}
/>
{#if primaryValue}
<button
on:click={() => onClearPrimary()}
type="reset"
class="spectrum-ClearButton spectrum-Search-clearButton"
>
<svg
class="spectrum-Icon spectrum-UIIcon-Cross75"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Cross75" />
</svg>
</button>
{/if}
</div>
{#if primaryOpen}
<div
@ -160,7 +181,7 @@
transition:fly|local={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
class:auto-width={autoWidth}
style="width: 70%"
class:is-full-width={!secondaryOptions.length}
>
<ul class="spectrum-Menu" role="listbox">
{#if placeholderOption}
@ -250,78 +271,82 @@
</ul>
</div>
{/if}
<div style="width: 30%">
<button
{id}
class="spectrum-Picker spectrum-Picker--sizeM override-borders"
{disabled}
class:is-open={secondaryOpen}
aria-haspopup="listbox"
on:mousedown={onClickSecondary}
>
{#if secondaryFieldIcon}
<span class="option-left">
<Icon name={secondaryFieldIcon} />
</span>
{:else if secondaryFieldColour}
<span class="option-left">
<StatusLight color={secondaryFieldColour} />
</span>
{/if}
<span class:auto-width={autoWidth} class="spectrum-Picker-label">
{secondaryFieldText}
</span>
<svg
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
focusable="false"
aria-hidden="true"
{#if secondaryOptions.length}
<div style="width: 30%">
<button
{id}
class="spectrum-Picker spectrum-Picker--sizeM override-borders"
{disabled}
class:is-open={secondaryOpen}
aria-haspopup="listbox"
on:mousedown={onClickSecondary}
>
<use xlink:href="#spectrum-css-icon-Chevron100" />
</svg>
</button>
{#if secondaryOpen}
<div
use:clickOutside={() => (secondaryOpen = false)}
transition:fly|local={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
style="width: 30%"
>
<ul class="spectrum-Menu" role="listbox">
{#each secondaryOptions as option, idx}
<li
class="spectrum-Menu-item"
class:is-selected={isOptionSelected(
getSecondaryOptionValue(option, idx)
)}
role="option"
aria-selected="true"
tabindex="0"
on:click={() =>
onPickSecondary(getSecondaryOptionValue(option, idx))}
>
{#if getSecondaryOptionColour(option, idx)}
<span class="option-left">
<StatusLight color={getSecondaryOptionColour(option, idx)} />
</span>
{/if}
{#if secondaryFieldIcon}
<span class="option-left">
<Icon name={secondaryFieldIcon} />
</span>
{:else if secondaryFieldColour}
<span class="option-left">
<StatusLight color={secondaryFieldColour} />
</span>
{/if}
<span class="spectrum-Menu-itemLabel">
{getSecondaryOptionLabel(option, idx)}
</span>
<svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false"
aria-hidden="true"
<span class:auto-width={autoWidth} class="spectrum-Picker-label">
{secondaryFieldText}
</span>
<svg
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Chevron100" />
</svg>
</button>
{#if secondaryOpen}
<div
use:clickOutside={() => (secondaryOpen = false)}
transition:fly|local={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
style="width: 30%"
>
<ul class="spectrum-Menu" role="listbox">
{#each secondaryOptions as option, idx}
<li
class="spectrum-Menu-item"
class:is-selected={isOptionSelected(
getSecondaryOptionValue(option, idx)
)}
role="option"
aria-selected="true"
tabindex="0"
on:click={() =>
onPickSecondary(getSecondaryOptionValue(option, idx))}
>
<use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg>
</li>
{/each}
</ul>
</div>
{/if}
</div>
{#if getSecondaryOptionColour(option, idx)}
<span class="option-left">
<StatusLight
color={getSecondaryOptionColour(option, idx)}
/>
</span>
{/if}
<span class="spectrum-Menu-itemLabel">
{getSecondaryOptionLabel(option, idx)}
</span>
<svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg>
</li>
{/each}
</ul>
</div>
{/if}
</div>
{/if}
</div>
<style>
@ -381,4 +406,25 @@
.labelPadding {
padding-left: calc(1em + 10px + 8px);
}
.spectrum-Textfield.spectrum-InputGroup-textfield {
width: 70%;
}
.spectrum-Textfield.spectrum-InputGroup-textfield.is-full-width {
width: 100%;
}
.spectrum-Textfield.spectrum-InputGroup-textfield.is-full-width input {
border-right-width: thin;
}
.spectrum-Popover.spectrum-Popover--bottom.spectrum-Picker-popover.is-open {
width: 70%;
}
.spectrum-Popover.spectrum-Popover--bottom.spectrum-Picker-popover.is-open.is-full-width {
width: 100%;
}
.spectrum-Search-clearButton {
position: absolute;
}
</style>

View File

@ -71,9 +71,9 @@
}
const onPickPrimary = e => {
primaryLabel = e.detail.label
primaryValue = e.detail.value
dispatch("pickprimary", e.detail.value)
primaryLabel = e?.detail?.label || null
primaryValue = e?.detail?.value || null
dispatch("pickprimary", e?.detail?.value || {})
}
const onPickSecondary = e => {

View File

@ -0,0 +1,43 @@
<script>
import { PickerDropdown, notifications } from "@budibase/bbui"
import { groups } from "stores/portal"
import { onMount, createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
$: optionSections = {
groups: {
data: $groups,
getLabel: group => group.name,
getValue: group => group._id,
getIcon: group => group.icon,
getColour: group => group.color,
},
}
$: appData = [{ id: "", role: "" }]
$: onChange = selected => {
const { detail } = selected
if (!detail) return
const groupSelected = $groups.find(x => x._id === detail)
const appIds = groupSelected?.apps.map(x => x.appId) || null
dispatch("change", appIds)
}
onMount(async () => {
try {
await groups.actions.init()
} catch (error) {
notifications.error("Error")
}
})
</script>
<PickerDropdown
autocomplete
primaryOptions={optionSections}
placeholder={"Filter by access"}
on:pickprimary={onChange}
/>

View File

@ -20,12 +20,13 @@
import { store, automationStore } from "builderStore"
import { API } from "api"
import { onMount } from "svelte"
import { apps, auth, admin, templates } from "stores/portal"
import { apps, auth, admin, templates, groups } from "stores/portal"
import download from "downloadjs"
import { goto } from "@roxi/routify"
import AppRow from "components/start/AppRow.svelte"
import { AppStatus } from "constants"
import Logo from "assets/bb-space-man.svg"
import AccessFilter from "./_components/AcessFilter.svelte"
let sortBy = "name"
let template
@ -39,6 +40,7 @@
let cloud = $admin.cloud
let creatingFromTemplate = false
let automationErrors
let accessFilterList = null
const resolveWelcomeMessage = (auth, apps) => {
const userWelcome = auth?.user?.firstName
@ -56,8 +58,10 @@
: "Start from scratch"
$: enrichedApps = enrichApps($apps, $auth.user, sortBy)
$: filteredApps = enrichedApps.filter(app =>
app?.name?.toLowerCase().includes(searchTerm.toLowerCase())
$: filteredApps = enrichedApps.filter(
app =>
app?.name?.toLowerCase().includes(searchTerm.toLowerCase()) &&
(accessFilterList !== null ? accessFilterList.includes(app?.appId) : true)
)
$: lockedApps = filteredApps.filter(app => app?.lockedYou || app?.lockedOther)
@ -202,6 +206,10 @@
$goto(`../../app/${app.devId}`)
}
const accessFilterAction = accessFilter => {
accessFilterList = accessFilter.detail
}
function createAppFromTemplateUrl(templateKey) {
// validate the template key just to make sure
const templateParts = templateKey.split("/")
@ -347,6 +355,9 @@
</Button>
{/if}
<div class="filter">
{#if $groups.length}
<AccessFilter on:change={accessFilterAction} />
{/if}
<Select
quiet
autoWidth