Skip to content

Commit ef853e5

Browse files
authored
Next: November Improvements (#1760)
Improved code generation Resolved many svelte 5 issues Lots of improvements to grids and layout. Fixed app constantly refreshing due to chatty web sockets.
2 parents 5cf8ad8 + af8cc53 commit ef853e5

File tree

30 files changed

+969
-700
lines changed

30 files changed

+969
-700
lines changed

src/Exceptionless.Web/ClientApp.angular/components/billing/change-plan-dialog.tpl.html

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,14 @@ <h4>{{::'Credit Card' | translate}}</h4>
184184
<button type="button" role="button" class="btn btn-default" ng-click="vm.cancel()">
185185
{{::'Cancel' | translate}}
186186
</button>
187-
<span ng-if="vm.isCancellingPlan()">
188-
<button type="submit" role="button" class="btn btn-primary" ng-click="vm.showIntercom()">
189-
{{::'Contact Us' | translate}}
190-
</button>
191-
</span>
192-
<span ng-if="!vm.isCancellingPlan()">
193-
<button
194-
type="submit"
195-
role="button"
196-
class="btn btn-primary"
197-
promise-button="vm.save(vm.changePlanForm.$valid)"
198-
promise-button-busy-text="{{::'Changing Plan' | translate}}"
199-
>
200-
{{::'Change Plan' | translate}}
201-
</button>
202-
</span>
187+
<button
188+
type="submit"
189+
role="button"
190+
class="btn btn-primary"
191+
promise-button="vm.save(vm.changePlanForm.$valid)"
192+
promise-button-busy-text="{{::'Changing Plan' | translate}}"
193+
>
194+
{{::'Change Plan' | translate}}
195+
</button>
203196
</div>
204197
</form>

src/Exceptionless.Web/ClientApp/api-templates/class-data-contract.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export class <%~ contract.name %> {
66
<% for (const field of contract.$content) { %>
77
<%~ includeFile('@base/object-field-jsdoc.ejs', { ...it, field }) %>
88
<%~ includeFile('./object-field-class-validator.ejs', { ...it, field }) %>
9-
<%~ field.name %><%~ field.isRequired || field.nullable !== true ? '!' : '' %>: <%~ field.value.replaceAll('any', 'unknown') %><%~ field.type === "object" && field.nullable === true ? ' | null' : '' %><%~ field.nullable === true ? ' = null' : '' %>;
9+
<%~ field.name %><%~ field.isRequired || !field.nullable ? '!' : '' %><%~ field.nullable ? '?' : '' %>: <%~ field.value.replaceAll('any', 'unknown') %>;
1010
<% } %>
1111
}
1212

src/Exceptionless.Web/ClientApp/api-templates/object-field-class-validator.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function getFormatValidation(field) {
2222
}
2323
2424
const validationDecorators = _.compact([
25-
!field.isRequired && "@IsOptional()",
25+
!field.isRequired && field.nullable && "@IsOptional()",
2626
(field.name === "id" || field.name.endsWith("_id")) && `@IsMongoId({ message: '${field.name} must be a valid ObjectId.' })`,
2727
field.name === "url" && `@IsUrl({}, { message: '${field.name} must be a valid URL.' })`,
2828
!_.isUndefined(field.format) && getFormatValidation(field),
@@ -32,7 +32,7 @@ const validationDecorators = _.compact([
3232
!_.isUndefined(field.type) && (field.type === "object" || (field.type === "array" && field.items.$ref)) && `@ValidateNested({ message: '${field.name} must be a valid nested object.' })`,
3333
]);
3434
35-
if (!validationDecorators.length && field.isRequired) {
35+
if (!validationDecorators.length && (field.isRequired || !field.nullable)) {
3636
validationDecorators.push(`@IsDefined({ message: '${field.name} is required.' })`);
3737
}
3838

src/Exceptionless.Web/ClientApp/package-lock.json

Lines changed: 218 additions & 197 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Exceptionless.Web/ClientApp/package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,40 @@
2323
"upgrade": "ncu -i"
2424
},
2525
"devDependencies": {
26-
"@iconify-json/lucide": "^1.2.16",
26+
"@iconify-json/lucide": "^1.2.17",
2727
"@playwright/test": "^1.49.0",
2828
"@sveltejs/adapter-static": "^3.0.6",
29-
"@sveltejs/kit": "^2.8.3",
29+
"@sveltejs/kit": "^2.8.5",
3030
"@sveltejs/vite-plugin-svelte": "^4.0.2",
3131
"@types/eslint": "^9.6.1",
32-
"@types/node": "^22.9.3",
32+
"@types/node": "^22.10.1",
3333
"@types/throttle-debounce": "^5.0.2",
3434
"autoprefixer": "^10.4.20",
3535
"cross-env": "^7.0.3",
3636
"eslint": "^9.15.0",
3737
"eslint-config-prettier": "^9.1.0",
38-
"eslint-plugin-perfectionist": "^4.0.3",
38+
"eslint-plugin-perfectionist": "^4.1.2",
3939
"eslint-plugin-svelte": "^2.46.0",
4040
"npm-run-all": "^4.1.5",
4141
"postcss": "^8.4.49",
42-
"prettier": "^3.3.3",
42+
"prettier": "^3.4.1",
4343
"prettier-plugin-svelte": "^3.3.2",
4444
"prettier-plugin-tailwindcss": "^0.6.9",
45-
"svelte": "^5.2.7",
45+
"svelte": "^5.2.10",
4646
"svelte-check": "^4.1.0",
4747
"swagger-typescript-api": "^13.0.23",
4848
"tslib": "^2.8.1",
4949
"typescript": "^5.7.2",
50-
"typescript-eslint": "^8.15.0",
50+
"typescript-eslint": "^8.16.0",
5151
"vite": "^5.4.11",
52-
"vitest": "^2.1.5"
52+
"vitest": "^2.1.6"
5353
},
5454
"dependencies": {
5555
"@exceptionless/browser": "^3.1.0",
5656
"@exceptionless/fetchclient": "^0.29.0",
5757
"@iconify-json/mdi": "^1.2.1",
58-
"@tanstack/svelte-query": "https://pkg.pr.new/@tanstack/svelte-query@ccce0b8",
59-
"@tanstack/svelte-query-devtools": "https://pkg.pr.new/@tanstack/svelte-query-devtools@ccce0b8",
58+
"@tanstack/svelte-query": "https://pkg.pr.new/@tanstack/svelte-query@28f98f9",
59+
"@tanstack/svelte-query-devtools": "https://pkg.pr.new/@tanstack/svelte-query-devtools@28f98f9",
6060
"@tanstack/svelte-table": "^9.0.0-alpha.10",
6161
"@typeschema/class-validator": "^0.3.0",
6262
"bits-ui": "^1.0.0-next.64",
@@ -66,7 +66,7 @@
6666
"mode-watcher": "^0.5.0",
6767
"oidc-client-ts": "^3.1.0",
6868
"pretty-ms": "^9.2.0",
69-
"runed": "^0.15.3",
69+
"runed": "^0.15.4",
7070
"svelte-sonner": "^0.3.28",
7171
"svelte-time": "^0.9.0",
7272
"sveltekit-superforms": "^2.20.1",
@@ -75,7 +75,7 @@
7575
"tailwindcss": "^3.4.15",
7676
"tailwindcss-animate": "^1.0.7",
7777
"throttle-debounce": "^5.0.2",
78-
"unplugin-icons": "^0.20.1"
78+
"unplugin-icons": "^0.20.2"
7979
},
8080
"type": "module"
8181
}

src/Exceptionless.Web/ClientApp/resources.md

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,116 +4,116 @@
44

55
### TODO
66

7-
- Investigate loading data in - export function load({ url, fetch }) {}
7+
- Investigate loading data in - export function load({ url, fetch }) {}
88

99
#### shadcn svelte upgrade
1010

11-
- on:
12-
- slots
11+
- on:
12+
- slots
1313

1414
#### sveltekit
1515

16-
- page.subscribe
17-
- get(
16+
- page.subscribe
17+
- get(
1818

1919
## General
2020

21-
- <https://kit.svelte.dev/docs/project-structure>
22-
- <https://github.com/laoshaw/sveltespa>
23-
- <https://khromov.se/the-missing-guide-to-understanding-adapter-static-in-sveltekit/>
24-
- <https://marketsplash.com/tutorials/svelte/svelte-onclick/>
21+
- <https://kit.svelte.dev/docs/project-structure>
22+
- <https://github.com/laoshaw/sveltespa>
23+
- <https://khromov.se/the-missing-guide-to-understanding-adapter-static-in-sveltekit/>
24+
- <https://marketsplash.com/tutorials/svelte/svelte-onclick/>
2525

2626
## Forms
2727

28-
- <https://joyofcode.xyz/sveltekit-progressive-enhancement>
29-
- <https://joyofcode.xyz/working-with-forms-in-sveltekit>
28+
- <https://joyofcode.xyz/sveltekit-progressive-enhancement>
29+
- <https://joyofcode.xyz/working-with-forms-in-sveltekit>
3030

3131
## Data Tables
3232

33-
- <https://github.com/TanStack/table>
34-
- <https://svelte-headless-table.bryanmylee.com/#headless>
35-
- <https://tanstack.com/table/v8/docs/guide/column-sizing>
36-
- <https://www.youtube.com/watch?v=-Zuo3UWjjI8>
37-
- <https://tanstack.com/table/v8/docs/examples/svelte/basic>
38-
- <https://codesandbox.io/examples/package/@tanstack/svelte-table>
39-
- <https://codesandbox.io/s/tanstack-table-example-svelte-basic-4jif2l?file=/src/App.svelte>
40-
- <https://tailwindcomponents.com/component/free-tailwind-css-advance-table-component>
41-
- <https://tailwindcomponents.com/component/table-1>
42-
- <https://tuk.dev/components/webapp/table/advance_table>
43-
- <https://github.dev/phartenfeller/sveltekit-1.0-sqlite-demo-app/tree/tut-13-tanstack-table-edit-row>
33+
- <https://github.com/TanStack/table>
34+
- <https://svelte-headless-table.bryanmylee.com/#headless>
35+
- <https://tanstack.com/table/v8/docs/guide/column-sizing>
36+
- <https://www.youtube.com/watch?v=-Zuo3UWjjI8>
37+
- <https://tanstack.com/table/v8/docs/examples/svelte/basic>
38+
- <https://codesandbox.io/examples/package/@tanstack/svelte-table>
39+
- <https://codesandbox.io/s/tanstack-table-example-svelte-basic-4jif2l?file=/src/App.svelte>
40+
- <https://tailwindcomponents.com/component/free-tailwind-css-advance-table-component>
41+
- <https://tailwindcomponents.com/component/table-1>
42+
- <https://tuk.dev/components/webapp/table/advance_table>
43+
- <https://github.dev/phartenfeller/sveltekit-1.0-sqlite-demo-app/tree/tut-13-tanstack-table-edit-row>
4444

4545
## State
4646

47-
- <https://joyofcode.xyz/svelte-context-with-stores>
48-
- <https://joyofcode.xyz/svelte-state-management>
47+
- <https://joyofcode.xyz/svelte-context-with-stores>
48+
- <https://joyofcode.xyz/svelte-state-management>
4949

5050
## Authentication
5151

52-
- <https://github.com/sveltejs/realworld>
53-
- <https://github.com/authts/oidc-client-ts>
54-
- <https://authjs.dev/reference/sveltekit>
55-
- <https://github.dev/rvs1257/svelte-zitadel-pkce>
56-
- <https://github.com/Dan6erbond/sk-auth>
57-
- <https://hartenfeller.dev/blog/sveltekit-diy-authentication-authorization>
58-
- <https://www.swyx.io/svelte-auth>
59-
- <https://ashutosh.dev/how-to-do-authentication-in-svelte-using-store/>
60-
- <https://www.reddit.com/r/sveltejs/comments/117tvx7/how_to_protect_routes_with_login_check/>
61-
- <https://github.dev/nextauthjs/sveltekit-auth-example>
62-
- <https://github.com/nstuyvesant/sveltekit-auth-example>
63-
- <https://authjs.dev/getting-started/credentials-tutorial>
64-
- <https://github.com/search?q=SvelteKitAuth+client&type=code&p=2>
65-
- <https://github.com/GeeTee/sveltekitAuth-directus/blob/master/src/routes/confidentiel/__layout.svelte>
66-
- <https://github.com/GeeTee/sveltekitAuth-directus-sdk/blob/master/src/routes/sign-out.svelte>
67-
- <https://github.com/nicklascarnegie/sveltekitauth-token-rotation-demo/blob/master/src/hooks.server.ts>
68-
- <https://joyofcode.xyz/sveltekit-authentication-using-cookies#passing-user-data-to-pages>
52+
- <https://github.com/sveltejs/realworld>
53+
- <https://github.com/authts/oidc-client-ts>
54+
- <https://authjs.dev/reference/sveltekit>
55+
- <https://github.dev/rvs1257/svelte-zitadel-pkce>
56+
- <https://github.com/Dan6erbond/sk-auth>
57+
- <https://hartenfeller.dev/blog/sveltekit-diy-authentication-authorization>
58+
- <https://www.swyx.io/svelte-auth>
59+
- <https://ashutosh.dev/how-to-do-authentication-in-svelte-using-store/>
60+
- <https://www.reddit.com/r/sveltejs/comments/117tvx7/how_to_protect_routes_with_login_check/>
61+
- <https://github.dev/nextauthjs/sveltekit-auth-example>
62+
- <https://github.com/nstuyvesant/sveltekit-auth-example>
63+
- <https://authjs.dev/getting-started/credentials-tutorial>
64+
- <https://github.com/search?q=SvelteKitAuth+client&type=code&p=2>
65+
- <https://github.com/GeeTee/sveltekitAuth-directus/blob/master/src/routes/confidentiel/__layout.svelte>
66+
- <https://github.com/GeeTee/sveltekitAuth-directus-sdk/blob/master/src/routes/sign-out.svelte>
67+
- <https://github.com/nicklascarnegie/sveltekitauth-token-rotation-demo/blob/master/src/hooks.server.ts>
68+
- <https://joyofcode.xyz/sveltekit-authentication-using-cookies#passing-user-data-to-pages>
6969

7070
## Theming
7171

72-
- <https://joyofcode.xyz/make-a-svelte-component-library>
73-
- <https://joyofcode.xyz/using-future-css-in-svelte>
74-
- <https://svelte.dev/repl/03f0be0c4dc54eb4af5a168f644f5c31?version=3.19.1>
75-
- <https://larainfo.com/blogs/tailwind-daisyui-registration-form-example>
76-
- <https://sveltethemes.dev/resources>
77-
- <https://tailwindui.com/components/application-ui/forms/sign-in-forms>
78-
- <https://daisyui.com/components/drawer/>
79-
- <https://tailwindcss.com/docs/customizing-colors>
80-
- <https://github.com/vaheqelyan/svelte-grid>
81-
- <https://svelte.dev/repl/329d9ab4b27543afaf735acfbc6bbec7?version=3.20.1>
82-
- <https://svelte.dev/repl/03f0be0c4dc54eb4af5a168f644f5c31?version=3.19.1>
83-
- <https://github.com/GeekyAnts/sb-admin-svelte>
72+
- <https://joyofcode.xyz/make-a-svelte-component-library>
73+
- <https://joyofcode.xyz/using-future-css-in-svelte>
74+
- <https://svelte.dev/repl/03f0be0c4dc54eb4af5a168f644f5c31?version=3.19.1>
75+
- <https://larainfo.com/blogs/tailwind-daisyui-registration-form-example>
76+
- <https://sveltethemes.dev/resources>
77+
- <https://tailwindui.com/components/application-ui/forms/sign-in-forms>
78+
- <https://daisyui.com/components/drawer/>
79+
- <https://tailwindcss.com/docs/customizing-colors>
80+
- <https://github.com/vaheqelyan/svelte-grid>
81+
- <https://svelte.dev/repl/329d9ab4b27543afaf735acfbc6bbec7?version=3.20.1>
82+
- <https://svelte.dev/repl/03f0be0c4dc54eb4af5a168f644f5c31?version=3.19.1>
83+
- <https://github.com/GeekyAnts/sb-admin-svelte>
8484

8585
## Storage
8686

87-
- <https://github.com/joshnuss/svelte-persisted-store>
87+
- <https://github.com/joshnuss/svelte-persisted-store>
8888

8989
## i18n
9090

91-
- <https://github.com/kaisermann/svelte-i18n>
92-
- <https://github.com/sveltekit-i18n/lib>
93-
- <https://github.com/nubolab-ffwd/svelte-fluent>
91+
- <https://github.com/kaisermann/svelte-i18n>
92+
- <https://github.com/sveltekit-i18n/lib>
93+
- <https://github.com/nubolab-ffwd/svelte-fluent>
9494

9595
## Validation
9696

97-
- <https://github.com/typestack/class-validator>
98-
- <https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0>
99-
- <https://github.com/DamianEdwards/MiniValidation>
100-
- <https://github.dev/DamianEdwards/MinimalApis.Extensions>
101-
- <https://benfoster.io/blog/minimal-api-validation-endpoint-filters/>
97+
- <https://github.com/typestack/class-validator>
98+
- <https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0>
99+
- <https://github.com/DamianEdwards/MiniValidation>
100+
- <https://github.dev/DamianEdwards/MinimalApis.Extensions>
101+
- <https://benfoster.io/blog/minimal-api-validation-endpoint-filters/>
102102

103103
## Networking
104104

105-
- <https://tanstack.com/query/v5/docs/svelte/examples/svelte/simple>
106-
- <https://kit.svelte.dev/docs/load>
107-
- <https://github.com/acacode/swagger-typescript-api>
108-
- <https://learn.microsoft.com/en-us/openapi/kiota/quickstarts/dotnet>
109-
- <https://github.com/microsoft/kiota/tree/main>
110-
- <https://learn.microsoft.com/en-us/openapi/kiota/quickstarts/typescript>
111-
- <https://medium.com/@wundergraph/introducing-the-new-svelte-query-client-836d6e961c>
112-
- <https://github.com/JacobLinCool/sveltekit-api>
113-
- <https://openapi.tools/>
114-
- <https://orval.dev/guides/svelte-query>
115-
- <https://github.com/drwpow/openapi-typescript>
116-
- <https://dev.to/fbjorn/a-typed-http-client-for-sveltekit-88b>
117-
- <https://github.com/OpenAPITools/openapi-generator-cli>
118-
- <https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch>
119-
- <https://dev.to/fbjorn/a-typed-http-client-for-sveltekit-88b>
105+
- <https://tanstack.com/query/v5/docs/svelte/examples/svelte/simple>
106+
- <https://kit.svelte.dev/docs/load>
107+
- <https://github.com/acacode/swagger-typescript-api>
108+
- <https://learn.microsoft.com/en-us/openapi/kiota/quickstarts/dotnet>
109+
- <https://github.com/microsoft/kiota/tree/main>
110+
- <https://learn.microsoft.com/en-us/openapi/kiota/quickstarts/typescript>
111+
- <https://medium.com/@wundergraph/introducing-the-new-svelte-query-client-836d6e961c>
112+
- <https://github.com/JacobLinCool/sveltekit-api>
113+
- <https://openapi.tools/>
114+
- <https://orval.dev/guides/svelte-query>
115+
- <https://github.com/drwpow/openapi-typescript>
116+
- <https://dev.to/fbjorn/a-typed-http-client-for-sveltekit-88b>
117+
- <https://github.com/OpenAPITools/openapi-generator-cli>
118+
- <https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch>
119+
- <https://dev.to/fbjorn/a-typed-http-client-for-sveltekit-88b>

src/Exceptionless.Web/ClientApp/src/lib/features/events/api.svelte.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
1+
import type { WebSocketMessageValue } from '$features/websockets/models';
2+
13
import { accessToken } from '$features/auth/index.svelte';
24
import { type ProblemDetails, useFetchClient } from '@exceptionless/fetchclient';
3-
import { createQuery, useQueryClient } from '@tanstack/svelte-query';
5+
import { createQuery, QueryClient, useQueryClient } from '@tanstack/svelte-query';
46

57
import type { PersistentEvent } from './models';
68

9+
export async function invalidatePersistentEventQueries(queryClient: QueryClient, message: WebSocketMessageValue<'PersistentEventChanged'>) {
10+
const { id, stack_id } = message;
11+
if (id) {
12+
await queryClient.invalidateQueries({ queryKey: queryKeys.id(id) });
13+
}
14+
15+
if (stack_id) {
16+
await queryClient.invalidateQueries({ queryKey: queryKeys.stacks(stack_id) });
17+
}
18+
19+
if (!id && !stack_id) {
20+
await queryClient.invalidateQueries({ queryKey: queryKeys.type });
21+
}
22+
}
23+
724
export const queryKeys = {
8-
all: ['PersistentEvent'] as const,
9-
allWithFilters: (filters: string) => [...queryKeys.all, { filters }] as const,
10-
id: (id: string | undefined) => [...queryKeys.all, id] as const,
11-
stacks: (id: string | undefined) => [...queryKeys.all, 'stacks', id] as const,
12-
stackWithFilters: (id: string | undefined, filters: string) => [...queryKeys.stacks(id), { filters }] as const
25+
id: (id: string | undefined) => [...queryKeys.type, id] as const,
26+
stacks: (id: string | undefined) => [...queryKeys.type, 'stacks', id] as const,
27+
type: ['PersistentEvent'] as const
1328
};
1429

1530
export interface GetEventByIdProps {

0 commit comments

Comments
 (0)