From a05cc97e486189037c554206e4a75a512fd2797a Mon Sep 17 00:00:00 2001 From: Vedran Zakanj Date: Wed, 7 Dec 2022 19:33:15 +0100 Subject: [PATCH 1/4] Remove svelte-spotlight package --- package-lock.json | 13 +------------ package.json | 3 +-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 79b24748..104e0cf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,7 @@ "version": "0.0.1", "dependencies": { "flexsearch": "^0.7.31", - "marked": "^4.2.2", - "svelte-spotlight": "^1.0.4" + "marked": "^4.2.2" }, "devDependencies": { "@algolia/client-search": "^4.14.1", @@ -4043,11 +4042,6 @@ "sourcemap-codec": "^1.4.8" } }, - "node_modules/svelte-spotlight": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/svelte-spotlight/-/svelte-spotlight-1.0.12.tgz", - "integrity": "sha512-1DbCtTef4Yhn7OBxg6mq0KclbldfN7DBwe8Hu1XahJ0eGz+i24Yc+HXF5TNBjpLRtNw2ogWFLNbmLaoW2RYL5g==" - }, "node_modules/tailwindcss": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", @@ -7360,11 +7354,6 @@ } } }, - "svelte-spotlight": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/svelte-spotlight/-/svelte-spotlight-1.0.12.tgz", - "integrity": "sha512-1DbCtTef4Yhn7OBxg6mq0KclbldfN7DBwe8Hu1XahJ0eGz+i24Yc+HXF5TNBjpLRtNw2ogWFLNbmLaoW2RYL5g==" - }, "tailwindcss": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", diff --git a/package.json b/package.json index 8092169b..3c7b5cb7 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "type": "module", "dependencies": { "flexsearch": "^0.7.31", - "marked": "^4.2.2", - "svelte-spotlight": "^1.0.4" + "marked": "^4.2.2" } } From 475cae3748cbdc225cb61299118f2282dd95e83b Mon Sep 17 00:00:00 2001 From: Vedran Zakanj Date: Wed, 7 Dec 2022 19:33:49 +0100 Subject: [PATCH 2/4] Copy spotlight component from svelte-spotlight and fix --- .../client/components/SearchModal.svelte | 2 +- .../spotlight/SvelteSpotlight.svelte | 376 ++++++++++++++++++ .../client/components/spotlight/index.ts | 80 ++++ 3 files changed, 457 insertions(+), 1 deletion(-) create mode 100644 src/lib/search/client/components/spotlight/SvelteSpotlight.svelte create mode 100644 src/lib/search/client/components/spotlight/index.ts diff --git a/src/lib/search/client/components/SearchModal.svelte b/src/lib/search/client/components/SearchModal.svelte index 926ba16d..2fde662c 100644 --- a/src/lib/search/client/components/SearchModal.svelte +++ b/src/lib/search/client/components/SearchModal.svelte @@ -1,5 +1,5 @@ + + + +{#key isOpen} + {#if isOpen} +
+
+
+ + + {#if headerCenterComponent} + + {:else} + + {/if} + +
+
+
+ {#if headerCenterComponent} + + {:else} + + {#if query.length === 0 && $$slots.emptySearch} + + {:else if noResults} + + {:else if !noResults} + {#if groupResultsKey} + {#each results as group, groupIndex (group[groupIdKey])} + {@const groupedResults = group[groupResultsKey]} + {#if groupedResults.length} + + + {#each groupedResults as result, index (result[resultIdKey])} + {@const selected = preSelectedResult?.[resultIdKey] === result[resultIdKey]} + select(result)} + > + + + {/each} + + {/if} + {/each} + {:else} + + {#each results as result, index (result[resultIdKey])} + {@const selected = preSelectedResult?.[resultIdKey] === result[resultIdKey]} + select(result)} + > + + + {/each} + + {/if} + {/if} + + {/if} +
+ +
+
+ +
+
+ {/if} +{/key} + + + + diff --git a/src/lib/search/client/components/spotlight/index.ts b/src/lib/search/client/components/spotlight/index.ts new file mode 100644 index 00000000..18008e2b --- /dev/null +++ b/src/lib/search/client/components/spotlight/index.ts @@ -0,0 +1,80 @@ +import type { + fade, + fly, + scale, + blur, + slide, + BlurParams, + CrossfadeParams, + FadeParams, + ScaleParams, + SlideParams +} from 'svelte/transition'; +import type { RequireExactlyOne } from 'type-fest'; + +export type Fade = typeof fade; +export type Fly = typeof fly; +export type Scale = typeof scale; +export type Blur = typeof blur; +export type Slide = typeof slide; + +export type AnimationFunctions = Fade | Fly | Scale | Blur | Slide; +export type AnimationConfig = Parameters[1]; +export type AnimatingParams = FadeParams & ScaleParams & CrossfadeParams & SlideParams & BlurParams; +export const scrollIntoViewIfNeeded = (target: HTMLLIElement, container: HTMLDivElement) => { + const top = target.offsetTop - container.offsetTop; + if ( + top + target.offsetTop / 2 > container.scrollTop + container.clientHeight || + top < container.scrollTop + ) + target.scrollIntoView({ block: 'center', inline: 'center' }); +}; + +export const isCombo = (e: KeyboardEvent, combo: T) => { + if (typeof combo === 'boolean') { + return; + } else { + return combo?.key === e.key && ((combo?.metaKey && e.metaKey) || (combo?.ctrlKey && e.ctrlKey)); + } +}; + +type defaultSlotProps = { + selectedResult: Result; + preSelectedResult: Result; + noResults: boolean; + query: string; +}; +export type Slots = { + headerLeft: defaultSlotProps; + headerRight: defaultSlotProps; + contentTop: defaultSlotProps; + contentBottom: defaultSlotProps; + emptySearch: defaultSlotProps; + noResults: defaultSlotProps; + groupHeader: defaultSlotProps & { + group: R; + groupIndex: number; + }; + result: defaultSlotProps & { + result: Result; + selected: boolean; + index: number; + }; + sidePanel: defaultSlotProps & { + maxHeight: number; + }; + trigger: defaultSlotProps & { + toggle: () => void; + }; + footer: defaultSlotProps; +}; + +export type Combo = + | (RequireExactlyOne< + { + metaKey?: boolean; + ctrlKey?: boolean; + }, + 'ctrlKey' | 'metaKey' + > & { key: string }) + | boolean; From 3edd24c12a69955ce59e4f93f14054dc4f78e406 Mon Sep 17 00:00:00 2001 From: Vedran Zakanj Date: Wed, 7 Dec 2022 19:38:17 +0100 Subject: [PATCH 3/4] Fix exception-handler text typo --- src/routes/docs/[...12]exception-handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/docs/[...12]exception-handler.md b/src/routes/docs/[...12]exception-handler.md index 0d110851..cfe00071 100644 --- a/src/routes/docs/[...12]exception-handler.md +++ b/src/routes/docs/[...12]exception-handler.md @@ -76,7 +76,7 @@ public override void Configure() ``` Do note however that by doing so, you are effectively disabling the automatic error responses sent by the library. It would then be the responsibility of your custom exception handling middleware to handle the exceptions and send appropriate responses to the requesting client. -The the thrown exception type is **ValidationFailureException**, which has a property called **Failures** where you can get access to a collection of **ValidationFailure** objects to check what sort of validation failures occurred. +The thrown exception type is **ValidationFailureException**, which has a property called **Failures** where you can get access to a collection of **ValidationFailure** objects to check what sort of validation failures occurred. ### The Better Approach From e801fc93a07c034ee71caba1d1a04367d00acb1e Mon Sep 17 00:00:00 2001 From: Vedran Zakanj Date: Wed, 7 Dec 2022 19:39:54 +0100 Subject: [PATCH 4/4] Remove old exception handler file I've renamed this file to correct filename exception-handler.md in my branch, i.e. removed the double dot. This was probably brought back through merging the PR, so removing it again since it causes a double Exception Handler entry in the sidebar --- src/routes/docs/[...13]exception-handler..md | 108 ------------------- 1 file changed, 108 deletions(-) delete mode 100644 src/routes/docs/[...13]exception-handler..md diff --git a/src/routes/docs/[...13]exception-handler..md b/src/routes/docs/[...13]exception-handler..md deleted file mode 100644 index cfe00071..00000000 --- a/src/routes/docs/[...13]exception-handler..md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Exception Handler -description: FastEndpoints has a built-in exception handler to help log uncaught errors in a convenient manner. ---- - -# {$frontmatter.title} - -## Unhandled Exception Handler - -The library ships with a default exception handler middleware you can use to log the exception details on the server and return a user-friendly HTTP 500 response to the requesting client. - -## Example JSON Response: - -```json | title=json -{ - "Status": "Internal Server Error!", - "Code": 500, - "Reason": "'x' is an invalid start of a value. Path: $.ValMin | LineNumber: 4...", - "Note": "See application log for stack trace." -} -``` - -## Example Server Log Entry: - -``` -fail: FastEndpoints.ExceptionHandler[0] - ================================= - HTTP: POST /inventory/adjust-stock - TYPE: JsonException - REASON: 'x' is an invalid start of a value. Path: $.ValMin | LineNumber: 4... - --------------------------------- - at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state,... - at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader,... - at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter,... - ... -``` - -## Enabling The Exception Handler - -Enable the middleware as shown below during app startup. - -```cs |copy|title=Program.cs -var builder = WebApplication.CreateBuilder(); -builder.Services.AddFastEndpoints(); - -var app = builder.Build(); -app.UseDefaultExceptionHandler(); //add this -app.UseAuthorization(); -app.UseFastEndpoints(); -app.Run(); -``` - -Disable the ASP.NET Core Diagnostic logging for unhandled exceptions in order to avoid duplicate log entries. - -```json |copy|title=appsettings.json -{ - "Logging": { - "LogLevel": { - "Default": "Warning", - "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware": "None" //add this - } -} -``` - -## Customizing The Exception Handler -If you'd like to modify the behavior of the above middleware, you can simply copy the [source code](https://github.com/FastEndpoints/Library/blob/main/Src/Library/Extensions/ExceptionHandlerExtensions.cs) and register your version instead. - -## Disable Validation Error Catching -By default, all validation errors thrown by the endpoints are caught internally and not thrown out to the middleware pipeline. If you need those thrown, you can instruct the endpoint to do so by doing the following: -```cs title=MyEndpoint.cs -public override void Configure() -{ - Get("throw-error"); - DontCatchExceptions(); -} -``` -Do note however that by doing so, you are effectively disabling the automatic error responses sent by the library. It would then be the responsibility of your custom exception handling middleware to handle the exceptions and send appropriate responses to the requesting client. - -The thrown exception type is **ValidationFailureException**, which has a property called **Failures** where you can get access to a collection of **ValidationFailure** objects to check what sort of validation failures occurred. - -### The Better Approach - -Instead of using a custom exception handling middleware, you could register a **global post-processor** like the following: - -```cs title=ErrorLoggerPostProcessor.cs -public class ErrorLogger : IGlobalPostProcessor -{ - public Task PostProcessAsync(object req, object res, HttpContext ctx, IReadOnlyCollection failures, CancellationToken ct) - { - if (failures.Count > 0) - { - var logger = ctx.Resolve>(); - logger.LogWarning("Validation error count: {@count}", failures.Count); - } - return Task.CompletedTask; - } -} -``` -Wire it up in app startup like so: -```cs title=Program.cs -app.UseFastEndpoints(c => -{ - c.Endpoints.Configurator = ep => - { - ep.PostProcessors(new ErrorLogger()); - }; -}); -``` \ No newline at end of file