From d8aaf069390bb31dadc253aed4c5901af0c70599 Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Tue, 13 Dec 2022 17:34:20 +0000 Subject: [PATCH 01/16] refactor(WIP): refactor event modal --- src/lib/components/eventModal.svelte | 312 +++++++++++++++++---------- src/lib/helpers/array.ts | 12 ++ 2 files changed, 215 insertions(+), 109 deletions(-) diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index 72b4e8d36b..c4f6b980d7 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -1,11 +1,15 @@ @@ -290,7 +329,7 @@ {#if showInput}
- +
- - + From 107a3e3150525b8b30cb1dc54466c0dd3e41db8d Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Wed, 14 Dec 2022 18:04:29 +0000 Subject: [PATCH 06/16] refactor: code organization --- src/lib/components/eventModal.svelte | 54 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index 5c4cc80245..b91ba051c6 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -154,35 +154,19 @@ } } - // State & Reactive Declarations - let selected = { - service: null as Service | null, - resource: null as Resource | null, - action: null as Action | null, - attribute: null as string | null - }; - let helper: string = null; - let customInput: string = null; - let showInput = false; - let copyParent: HTMLElement; - - $: available = { - services: services, - resources: selected.service?.resources || [], - actions: (selected.resource ? selected.resource?.actions : selected.service?.actions) || [], - attributes: selected.action?.attributes || [] - }; - // Event string helpers const serviceNames = services.map((s) => s.name); const isService = (s: string) => serviceNames.includes(s); + const resourceNames = services.flatMap((s) => s.resources.map((r) => r.name)); const isResource = (s: string) => resourceNames.includes(s); + const actionNames = [ ...services.flatMap((s) => s.actions.map((a) => a.name)), ...services.flatMap((s) => s.resources.flatMap((r) => r.actions.map((a) => a.name))) ]; const isAction = (s: string) => actionNames.includes(s); + const attributeNames = [ ...services.flatMap((s) => s.actions.flatMap((a) => a.attributes ?? [])), ...services.flatMap((s) => @@ -190,8 +174,28 @@ ) ]; const isAttribute = (s: string) => attributeNames.includes(s); + const isField = (s: string) => isService(s) || isResource(s) || isAction(s) || isAttribute(s); + // State & Reactive Declarations + let selected = { + service: null as Service | null, + resource: null as Resource | null, + action: null as Action | null, + attribute: null as string | null + }; + let helper: string = null; + let customInput: string = null; + let showInput = false; + let copyParent: HTMLElement; + + $: available = { + services: services, + resources: selected.service?.resources || [], + actions: (selected.resource ? selected.resource?.actions : selected.service?.actions) || [], + attributes: selected.action?.attributes || [] + }; + $: eventString = (function createEventString(): Array<{ value: string; description: string }> { let fields: string[] = []; @@ -221,6 +225,7 @@ } return fields.map((value, i, arr) => { + const prev = arr[i - 1]; let description = value; if (isService(value)) { @@ -229,15 +234,10 @@ description = 'resource'; } else if (isAction(value)) { description = 'action'; - } else if (isAttribute(value)) { + } else if (isAttribute(value) || isAction(prev)) { description = 'attribute'; - } else if (i > 0) { - const prev = arr[i - 1]; - if (isAction(prev)) { - description = 'attribute'; - } else if (isField(prev)) { - description = `ID of ${prev.slice(0, -1)}`; - } + } else if (isField(prev)) { + description = `ID of ${prev.slice(0, -1)}`; } return { value, description }; From df29f3e28f2b07d01e1a46674bb60f8197dee1a9 Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Wed, 14 Dec 2022 18:57:47 +0000 Subject: [PATCH 07/16] feat: custom input helper --- src/lib/components/eventModal.svelte | 79 +++++++++++++++++++++------- src/lib/helpers/array.ts | 34 ++++++++++++ 2 files changed, 94 insertions(+), 19 deletions(-) diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index b91ba051c6..3686b8fad5 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -3,7 +3,7 @@ import { Modal } from '$lib/components'; import { Pill } from '$lib/elements'; import { createEventDispatcher } from 'svelte'; - import { empty } from '$lib/helpers/array'; + import { at, empty, last } from '$lib/helpers/array'; import Copy from './copy.svelte'; // Props @@ -154,6 +154,56 @@ } } + function resetSelected() { + Object.keys(selected).forEach((key) => (selected[key] = null)); + } + + function toggleShowInput(e?: Event) { + e?.preventDefault(); + + showInput = !showInput; + if (showInput) return; + + helper = null; + + resetSelected(); + + for (const field of customInput.split('.')) { + if (isService(field)) { + selected.service = services.find((s) => s.name === field); + } else if (isResource(field)) { + const resource = selected.service?.resources.find((r) => r.name === field); + selected.resource = resource; + } else if (isAction(field)) { + const action = + selected.resource?.actions.find((a) => a.name === field) || + selected.service?.actions.find((a) => a.name === field); + selected.action = action; + } else if (isAttribute(field)) { + const attribute = selected.action?.attributes?.find((a) => a === field); + selected.attribute = attribute; + } + } + } + + function getHelperStr(input: string): string { + const fields = input.split('.'); + const secondToLastField = at(fields, -3); + const prevField = at(fields, -2); + const currField = last(fields); + + if (fields.length === 1) return 'service'; + if (isAttribute(currField) || isAction(prevField)) return 'attribute'; + if (isAction(currField)) return 'action'; + if (isResource(currField)) return 'resource'; + if (isService(currField)) return 'service'; + if (isService(prevField) || isResource(prevField)) return `ID of ${prevField}`; + if (isService(secondToLastField)) return 'resource or action'; + if (isResource(secondToLastField)) return 'action'; + + return ''; + } + // Event string helpers const serviceNames = services.map((s) => s.name); const isService = (s: string) => serviceNames.includes(s); @@ -246,16 +296,16 @@ $: inputValue = eventString.map((d) => d.value).join('.'); - $: if (!showInput) { - helper = null; - } - $: if (!show) { - Object.keys(selected).forEach((key) => (selected[key] = null)); + resetSelected(); helper = null; customInput = null; showInput = false; } + + $: if (showInput) { + helper = getHelperStr(customInput); + } @@ -331,23 +381,14 @@
- -
+

{helper ?? ''}

{:else}
@@ -368,7 +409,7 @@ - + diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte index 9313c97a00..ab6af3c11f 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte @@ -50,6 +50,10 @@ const eventSet: Writable> = writable(new Set()); let showEvents = false; + let eventValue: string; + $: if (!showEvents) { + eventValue = undefined; + } let areEventsDisabled = true; onMount(async () => { @@ -271,7 +275,15 @@ } function handleEvent(event: CustomEvent) { - eventSet.set($eventSet.add(event.detail)); + if (eventValue) { + const newSet = new Set( + [...$eventSet].map((e) => (e === eventValue ? event.detail : e)) + ); + eventSet.set(newSet); + } else { + eventSet.set($eventSet.add(event.detail)); + } + eventValue = null; } $: if (permissions) { @@ -370,16 +382,27 @@ {event} - - + +
+ + +
{/each} @@ -600,4 +623,4 @@ on:updated={handleVariableUpdated} /> {/if} - + From 6e8748095b44646ab90fa79030b29bd9bee74d91 Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Thu, 15 Dec 2022 13:46:01 +0000 Subject: [PATCH 12/16] refactor: move eventModal constants --- src/lib/components/eventModal.svelte | 138 +++++++-------------------- src/lib/constants.ts | 84 ++++++++++++++++ 2 files changed, 117 insertions(+), 105 deletions(-) diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index 46902b663c..d4207ad9e3 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -7,96 +7,19 @@ import Copy from './copy.svelte'; import { selectionStart } from '$lib/actions/selectionStart'; import { singular } from '$lib/helpers/string'; + import { + eventServices as services, + type EventAction, + type EventResource, + type EventService + } from '$lib/constants'; + import { tooltip } from '$lib/actions/tooltip'; // Props export let show = false; export let initialValue = ''; - // Types & Constants - type Service = { - name: string; - resources: Resource[]; - actions?: Action[]; - }; - - type Resource = { - name: string; - actions?: Action[]; - }; - - type Action = { - name: string; - attributes?: string[]; - }; - - const services: Array = [ - { - name: 'buckets', - resources: [ - { - name: 'files', - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - } - ], - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'databases', - resources: [ - { - name: 'collections', - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'documents', - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - } - ], - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'functions', - resources: [ - { - name: 'deployments', - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'executions', - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - } - ], - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'teams', - resources: [ - { - name: 'memberships', - actions: [ - { name: 'create' }, - { name: 'update', attributes: ['status'] }, - { name: 'delete' } - ] - } - ], - actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] - }, - { - name: 'users', - resources: [ - { name: 'recovery', actions: [{ name: 'create' }, { name: 'delete' }] }, - { name: 'sessions', actions: [{ name: 'create' }, { name: 'delete' }] }, - { name: 'verifications', actions: [{ name: 'create' }, { name: 'delete' }] } - ], - actions: [ - { name: 'create' }, - { name: 'update', attributes: ['email', 'name', 'password', 'status', 'prefs'] }, - { name: 'delete' } - ] - } - ]; - + // Constants const serviceNames = services.map((s) => s.name); const resourceNames = services.flatMap((s) => s.resources.map((r) => r.name)); const actionNames = [ @@ -123,11 +46,11 @@ dispatch('created', inputValue); } - function select(field: 'service', value: Service); - function select(field: 'resource', value: Resource); - function select(field: 'action', value: Action); + function select(field: 'service', value: EventService); + function select(field: 'resource', value: EventResource); + function select(field: 'action', value: EventAction); function select(field: 'attribute', value: string); - function select(field: string, value: string | Service | Resource | Action) { + function select(field: string, value: string | EventService | EventResource | EventAction) { if (typeof value === 'string') { selected[field as 'attribute'] = selected[field] === value ? null : value; } else { @@ -220,6 +143,7 @@ if (isService(prevField) || isResource(prevField) || index === 1) { return `ID of ${singular(prevField)}`; } + // TODO: Find better name for 'resource or action' if (isService(secondToLastField) || index === 2) return 'resource or action'; if (isResource(secondToLastField)) return 'action'; @@ -249,9 +173,9 @@ // State & Reactive Declarations let selected = { - service: null as Service | null, - resource: null as Resource | null, - action: null as Action | null, + service: null as EventService | null, + resource: null as EventResource | null, + action: null as EventAction | null, attribute: null as string | null }; let helper: string = null; @@ -418,22 +342,26 @@ {/each}
- - + + + {/key}

{helper ?? ''}

diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 721c3db12a..a27a1c21de 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -174,3 +174,87 @@ export const scopes: { category: 'Other' } ]; + +export type EventService = { + name: string; + resources: EventResource[]; + actions?: EventAction[]; +}; + +export type EventResource = { + name: string; + actions?: EventAction[]; +}; + +export type EventAction = { + name: string; + attributes?: string[]; +}; + +export const eventServices: Array = [ + { + name: 'buckets', + resources: [ + { + name: 'files', + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + } + ], + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'databases', + resources: [ + { + name: 'collections', + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'documents', + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + } + ], + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'functions', + resources: [ + { + name: 'deployments', + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'executions', + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + } + ], + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'teams', + resources: [ + { + name: 'memberships', + actions: [ + { name: 'create' }, + { name: 'update', attributes: ['status'] }, + { name: 'delete' } + ] + } + ], + actions: [{ name: 'create' }, { name: 'update' }, { name: 'delete' }] + }, + { + name: 'users', + resources: [ + { name: 'recovery', actions: [{ name: 'create' }, { name: 'delete' }] }, + { name: 'sessions', actions: [{ name: 'create' }, { name: 'delete' }] }, + { name: 'verifications', actions: [{ name: 'create' }, { name: 'delete' }] } + ], + actions: [ + { name: 'create' }, + { name: 'update', attributes: ['email', 'name', 'password', 'status', 'prefs'] }, + { name: 'delete' } + ] + } +]; From df3544e1033022c1843d226f0f81120e32a25f0d Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Thu, 15 Dec 2022 19:19:52 +0000 Subject: [PATCH 13/16] refactor: separate updateEvents & use droplist for event options --- .../function-[function]/settings/+page.svelte | 154 ++---------------- .../settings/updateEvents.svelte | 144 ++++++++++++++++ 2 files changed, 160 insertions(+), 138 deletions(-) create mode 100644 src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte index ab6af3c11f..23dea10c9a 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte @@ -1,37 +1,26 @@ @@ -370,60 +307,7 @@ -
- - Update Events -

Set the events that will trigger your function. Maximum 100 events allowed.

- - {#if $eventSet.size} - - {#each Array.from($eventSet) as event} -
  • - - {event} - - -
    - - -
    -
    -
  • - {/each} -
    - -
    - -
    - {:else} - (showEvents = true)}>Add an event to get started - {/if} -
    - - - - -
    -
    +
    @@ -484,10 +368,6 @@ Download .env file -
    @@ -622,5 +502,3 @@ on:created={handleVariableCreated} on:updated={handleVariableUpdated} /> {/if} - - diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte new file mode 100644 index 0000000000..901b53c731 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte @@ -0,0 +1,144 @@ + + + + + Update Events +

    Set the events that will trigger your function. Maximum 100 events allowed.

    + + {#if $eventSet.size} + + {#each Array.from($eventSet) as event, i} +
  • + + {event} + + + + + + { + showDropdown[i] = false; + showEvents = true; + eventValue = event; + }}> + Edit + + { + $eventSet.delete(event); + eventSet.set($eventSet); + }}> + Delete + + + + +
  • + {/each} +
    + +
    + +
    + {:else} + (showEvents = true)}>Add an event to get started + {/if} +
    + + + + +
    + + + From bb2f10e84520fa0034801a1a68ea55d419780234 Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Thu, 15 Dec 2022 19:21:52 +0000 Subject: [PATCH 14/16] fix: event action naming convetions --- src/lib/components/eventModal.svelte | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index d4207ad9e3..9aadc6828c 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -218,8 +218,6 @@ } if (selected.attribute) { fields.push(selected.attribute); - } else if (selected.action?.attributes) { - fields.push('*'); } } From bf14907540e44ab69e84e80b8f5d892f9dbdb606 Mon Sep 17 00:00:00 2001 From: tglide <26071571+TGlide@users.noreply.github.com> Date: Mon, 23 Jan 2023 17:00:54 +0000 Subject: [PATCH 15/16] refactor: pr reviews --- src/lib/components/copy.svelte | 2 +- src/lib/components/eventModal.svelte | 12 ++++++------ tsconfig.json | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/components/copy.svelte b/src/lib/components/copy.svelte index 7fd1cb18bb..f1690ce8cb 100644 --- a/src/lib/components/copy.svelte +++ b/src/lib/components/copy.svelte @@ -6,7 +6,7 @@ export let value: string; export let event: string = null; - export let appendTo: any | undefined = undefined; + export let appendTo: Parameters['1']['appendTo'] = undefined; let content = 'Click to copy'; diff --git a/src/lib/components/eventModal.svelte b/src/lib/components/eventModal.svelte index 9aadc6828c..09d07e93c1 100644 --- a/src/lib/components/eventModal.svelte +++ b/src/lib/components/eventModal.svelte @@ -54,7 +54,7 @@ if (typeof value === 'string') { selected[field as 'attribute'] = selected[field] === value ? null : value; } else { - selected[field as any] = (selected[field] as any)?.name === value.name ? null : value; + selected[field] = selected[field]?.name === value.name ? null : value; } customInput = null; @@ -121,8 +121,8 @@ } } - function toggleShowInput(e?: Event) { - e?.preventDefault(); + function toggleShowInput(e: Event) { + e.preventDefault(); showInput = !showInput; if (showInput) return; @@ -326,7 +326,7 @@ {:else}
    -
    +
    {#each eventString as route, i} {#key copyParent}
    {:else}
    -
    + +
    {#each eventString as route, i}