Skip to content

Commit

Permalink
Fix linting issues and run prettier (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixTJDietrich authored Aug 6, 2024
1 parent 9e90f7f commit 29a1350
Show file tree
Hide file tree
Showing 23 changed files with 166 additions and 203 deletions.
6 changes: 2 additions & 4 deletions webapp/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = [
{
ignores: [
'.cache/',
'.angular/',
'.git/',
'.github/',
'build/',
Expand Down Expand Up @@ -54,10 +55,7 @@ module.exports = [
style: 'kebab-case',
},
],
'@angular-eslint/prefer-standalone': 'error',
'@angular-eslint/template/prefer-ngsrc': 'error',
'@angular-eslint/template/prefer-self-closing-tags': 'error',
'@angular-eslint/template/prefer-control-flow': 'error',
'@typescript-eslint/no-empty-object-type': 'off',
},
},
{
Expand Down
8 changes: 4 additions & 4 deletions webapp/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<p>Header</p>
</header>
<div class="flex gap-2 m-2 flex-col items-start">
<counter title="First Counter"/>
<counter title="Second Counter" [byCount]="16"/>
<app-counter title="First Counter" />
<app-counter title="Second Counter" [byCount]="16" />
</div>
<hello />
<app-hello />
<router-outlet />
</main>
</main>
2 changes: 1 addition & 1 deletion webapp/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { HelloComponent } from './example/hello/hello.component';
standalone: true,
imports: [RouterOutlet, CounterComponent, HelloComponent],
templateUrl: './app.component.html',
styles: [],
styles: []
})
export class AppComponent {
title = 'Hephaestus';
Expand Down
12 changes: 4 additions & 8 deletions webapp/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { ApplicationConfig, importProvidersFrom, provideExperimentalZonelessChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import {
provideAngularQuery,
QueryClient,
} from '@tanstack/angular-query-experimental'
import {LucideAngularModule, Home } from "lucide-angular";
import { provideAngularQuery, QueryClient } from '@tanstack/angular-query-experimental';
import { LucideAngularModule, Home } from 'lucide-angular';
import { routes } from './app.routes';
import { BASE_PATH } from './core/modules/openapi';


export const appConfig: ApplicationConfig = {
providers: [
provideExperimentalZonelessChangeDetection(),
provideRouter(routes),
provideAngularQuery(new QueryClient()),
{ provide: BASE_PATH, useValue: "http://localhost:8080" },
{ provide: BASE_PATH, useValue: 'http://localhost:8080' },
provideHttpClient(withInterceptorsFromDi()),
importProvidersFrom(LucideAngularModule.pick({ Home }))
]
};
};
24 changes: 14 additions & 10 deletions webapp/src/app/example/counter/counter.component.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
<div class="border rounded-md p-2 shadow-md">
<h3 class="text-xl font-medium">Counter Title: {{title()}}</h3>
<p>Value: {{counter()}}<p>
<p>HexValue: {{hexCounter()}}<p>
<app-button (click)="increment()">
Increment
@if (byCount() > 1) {
by {{byCount()}}
}
</app-button>
<h3 class="text-xl font-medium">Counter Title: {{ title() }}</h3>
<p>Value: {{ counter() }}</p>
<p></p>
<p>HexValue: {{ hexCounter() }}</p>
<p>
<app-button (click)="increment()">
Increment
@if (byCount() > 1) {
by {{ byCount() }}
}
</app-button>
</p>

<h4 class="text-lg font-medium">History</h4>
<div>
@for (item of counterHistory(); track item.dec) {
{{ item.dec }}
}
</div>
</div>
</div>
19 changes: 10 additions & 9 deletions webapp/src/app/example/counter/counter.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ interface CounterHistoryEntry {
}

@Component({
selector: 'counter',
selector: 'app-counter',
standalone: true,
imports: [AppButtonComponent],
templateUrl: './counter.component.html',
templateUrl: './counter.component.html'
})
export class CounterComponent {
// we put all our application data inside signals! -> most optimal change detection and re-rendering possible
Expand All @@ -26,17 +26,18 @@ export class CounterComponent {
// Pitfall: conditional logic inside computed
// When calling computed initially the dependency signal has to be called, otherwise it will not work
return this.counter().toString(16);
})
});

counterHistory = signal<CounterHistoryEntry[]>([{ dec: 0, hex: "0" }])
counterHistory = signal<CounterHistoryEntry[]>([{ dec: 0, hex: '0' }]);

constructor() {
console.log(`counter value: ${this.counter()}`);

// `effect`s goes in constructor (?)
// `effectRef` is not necessary, only if needed
// Runs once when the effect is declared to collect dependencies, and again when they change
const effectRef = effect((onCleanup) => {
// const effectRef =
effect((onCleanup) => {
const currentCount = this.counter();
const currentHexCount = this.hexCounter();

Expand All @@ -46,8 +47,8 @@ export class CounterComponent {

onCleanup(() => {
console.log('Perform cleanup action here');
})
})
});
});

// effectRef.destroy() at any time! Usually not necessary

Expand All @@ -57,9 +58,9 @@ export class CounterComponent {

increment() {
console.log('Updating counter...');
this.counter.update(counter => counter + this.byCount());
this.counter.update((counter) => counter + this.byCount());

// Update values of a signal only through Signals API, e.g.`set()` and `update()`, not directly (i.e. `push()`)
this.counterHistory.update(history => [...history, { dec: this.counter(), hex: this.hexCounter() }])
this.counterHistory.update((history) => [...history, { dec: this.counter(), hex: this.hexCounter() }]);
}
}
10 changes: 5 additions & 5 deletions webapp/src/app/example/counter/counter.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const meta: Meta<CounterComponent> = {
component: CounterComponent,
tags: ['autodocs'],
argTypes: toArgs<CounterComponent>({
title: "test",
byCount: 2,
}),
title: 'test',
byCount: 2
})
};

export default meta;
Expand All @@ -21,5 +21,5 @@ export const Primary: Story = {
args: {
title: 'Counter',
byCount: 2
},
};
}
};
6 changes: 3 additions & 3 deletions webapp/src/app/example/counter/counter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { signal } from "@angular/core";
import { signal } from '@angular/core';

export const counter = signal(0);

Expand All @@ -18,9 +18,9 @@ export const counter = signal(0);
// // inject any dependencies you need here
// }
//
// // anyone needing to modify the signal
// // anyone needing to modify the signal
// // needs to do so in a controlled way
// incrementCounter() {
// this.counterSignal.update((val) => val + 1);
// }
// }
// }
24 changes: 11 additions & 13 deletions webapp/src/app/example/hello/hello.component.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
import { Component, inject } from '@angular/core';
import { injectMutation, injectQuery, injectQueryClient } from '@tanstack/angular-query-experimental';
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental';
import { lastValueFrom } from 'rxjs';
import { HelloService } from 'app/core/modules/openapi';
import { AppButtonComponent } from 'app/ui/button/button/button.component';

@Component({
selector: 'hello',
selector: 'app-hello',
standalone: true,
imports: [AppButtonComponent, AngularQueryDevtools],
templateUrl: './hello.component.html'
})
export class HelloComponent {
helloService = inject(HelloService)
queryClient = injectQueryClient()
helloService = inject(HelloService);
queryClient = injectQueryClient();

query = injectQuery(() => ({
queryKey: ['hellos'],
queryFn: async () => lastValueFrom(this.helloService.getAllHellos()),
})
);
queryFn: async () => lastValueFrom(this.helloService.getAllHellos())
}));

mutation = injectMutation(() => ({
mutationFn: () => lastValueFrom(this.helloService.addHello()),
onSuccess: () =>
onSuccess: () =>
this.queryClient.invalidateQueries({
queryKey: ['hellos'],
}),
})
);
queryKey: ['hellos']
})
}));

addHello() {
this.mutation.mutate();
}
}
}
46 changes: 20 additions & 26 deletions webapp/src/app/storybook.helper.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { InputSignalWithTransform, InputSignal, EventEmitter } from '@angular/core';
import { Args, ArgTypes } from '@storybook/angular';
import { cva as CVA } from 'class-variance-authority';
import { ClassProp, ClassValue, StringToBoolean } from 'class-variance-authority/types';

// Source:
// https://stackoverflow.com/questions/78379300/how-do-i-use-angular-input-signals-with-storybook
export function toArgs<Component>(
args: Partial<TransformSignalInputType<TransformEventType<Component>>>
): TransformEventType<Component> {
export function toArgs<Component>(args: Partial<TransformSignalInputType<TransformEventType<Component>>>): TransformEventType<Component> {
return args as unknown as TransformEventType<Component>;
}

Expand All @@ -22,28 +19,23 @@ type TransformSignalInputType<T> = {
};

// Type to extract the type from InputSignal or InputSignalWithTransform
type TransformInputType<T> =
T extends InputSignalWithTransform<infer U, any>
? U
: T extends InputSignal<infer U>
? U
: T;


type TransformInputType<T> = T extends InputSignalWithTransform<infer U, unknown> ? U : T extends InputSignal<infer U> ? U : T;

// CVA Storybook Helper
type ConfigSchema = Record<string, Record<string, ClassValue>>;
type ConfigVariants<T extends ConfigSchema> = {
[Variant in keyof T]?: StringToBoolean<keyof T[Variant]> | null | undefined;
[Variant in keyof T]?: StringToBoolean<keyof T[Variant]> | null | undefined;
};
type ConfigVariantsMulti<T extends ConfigSchema> = {
[Variant in keyof T]?: StringToBoolean<keyof T[Variant]> | StringToBoolean<keyof T[Variant]>[] | undefined;
[Variant in keyof T]?: StringToBoolean<keyof T[Variant]> | StringToBoolean<keyof T[Variant]>[] | undefined;
};
type Config<T> = T extends ConfigSchema ? {
variants?: T;
defaultVariants?: ConfigVariants<T>;
compoundVariants?: (T extends ConfigSchema ? (ConfigVariants<T> | ConfigVariantsMulti<T>) & ClassProp : ClassProp)[];
} : never;
type Config<T> = T extends ConfigSchema
? {
variants?: T;
defaultVariants?: ConfigVariants<T>;
compoundVariants?: (T extends ConfigSchema ? (ConfigVariants<T> | ConfigVariantsMulti<T>) & ClassProp : ClassProp)[];
}
: never;

function createCVAArgTypes<T extends ConfigSchema>(config?: Config<T>) {
if (!config?.variants) {
Expand All @@ -53,20 +45,22 @@ function createCVAArgTypes<T extends ConfigSchema>(config?: Config<T>) {
const variants = config?.variants;
return Object.fromEntries(
Object.entries(variants).map(([variant, options]) => {
const variantKey = variant as keyof T;
const optionsArray = Object.keys(options) as (keyof T[typeof variantKey])[];
return [variant, {
control: { type: 'select' },
options: optionsArray
}];
const optionsArray = Object.keys(options) as (keyof T[typeof variant])[];
return [
variant,
{
control: { type: 'select' },
options: optionsArray
}
];
})
);
}

function createCVADefaultArgs<T>(config?: Config<T>) {
return (config?.defaultVariants || {}) as {
[Variant in keyof T]: keyof T[Variant];
}
};
}

export function cva<T extends ConfigSchema>(base?: ClassValue, config?: Config<T>) {
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/app/ui/button/button/button.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<button [class]="computedClass()" [disabled]="disabled()" (click)="onClick.emit($event)">
<ng-content />
</button>
</button>
16 changes: 8 additions & 8 deletions webapp/src/app/ui/button/button/button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ const [buttonVariants, args, argTypes] = cva(
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
link: 'text-primary underline-offset-4 hover:underline'
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
icon: 'h-10 w-10'
}
},
defaultVariants: {
variant: 'default',
size: 'default',
},
size: 'default'
}
}
);

Expand All @@ -37,15 +37,15 @@ interface ButtonVariants extends VariantProps<typeof buttonVariants> {}
@Component({
selector: 'app-button',
standalone: true,
templateUrl: './button.component.html',
templateUrl: './button.component.html'
})
export class AppButtonComponent {
class = input<ClassValue>('');
class = input<ClassValue>('');
variant = input<ButtonVariants['variant']>('default');
size = input<ButtonVariants['size']>('default');
disabled = input<boolean>(false);

onClick = output<Event>();

computedClass = computed(() => cn(buttonVariants({ variant: this.variant(), size: this.size() }), this.class()));
}
}
Loading

0 comments on commit 29a1350

Please sign in to comment.