From f7e4c49670ea6b78b353d8cfd890a290266e6362 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 15 Sep 2024 12:32:47 +0200 Subject: [PATCH 1/2] add github colors to tailwind --- webapp/.storybook/preview.ts | 13 +++- webapp/package-lock.json | 33 +++++++- webapp/package.json | 1 + .../theme-switcher/theme-switcher.service.ts | 4 + webapp/src/index.html | 4 +- webapp/src/styles.css | 4 + webapp/tailwind.config.ts | 78 ++++++++++++++++++- 7 files changed, 133 insertions(+), 4 deletions(-) diff --git a/webapp/.storybook/preview.ts b/webapp/.storybook/preview.ts index 93bed5ea..98165e8e 100644 --- a/webapp/.storybook/preview.ts +++ b/webapp/.storybook/preview.ts @@ -1,5 +1,5 @@ import { applicationConfig, Preview } from '@storybook/angular'; -import { withThemeByClassName } from '@storybook/addon-themes'; +import { withThemeByClassName, withThemeByDataAttribute } from '@storybook/addon-themes'; import { DocsContainer } from '@storybook/blocks'; import { createElement } from 'react'; import { themes } from '@storybook/core/theming'; @@ -45,6 +45,9 @@ const preview: Preview = { ...theme, appContentBg: `hsl(${backgroundHSL})`, }; + el?.setAttribute('data-color-mode', currentTheme); + el?.setAttribute('data-light-theme', 'light'); + el?.setAttribute('data-dark-theme', 'dark'); return createElement(DocsContainer, props); }, }, @@ -57,6 +60,14 @@ const preview: Preview = { }, defaultTheme: 'light', }), + withThemeByDataAttribute({ + attributeName: 'data-color-mode', + themes: { + light: 'light', + dark: 'dark', + }, + defaultTheme: 'light', + }), applicationConfig(appConfig), ], }; diff --git a/webapp/package-lock.json b/webapp/package-lock.json index dfac4801..eafc5a17 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -16,6 +16,7 @@ "@angular/platform-browser": "18.2.1", "@angular/platform-browser-dynamic": "18.2.1", "@angular/router": "18.2.1", + "@primer/primitives": "^9.1.1", "@tanstack/angular-query-devtools-experimental": "5.52.0", "@tanstack/angular-query-experimental": "5.52.0", "autoprefixer": "10.4.20", @@ -4410,6 +4411,29 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@prettier/sync": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@prettier/sync/-/sync-0.5.2.tgz", + "integrity": "sha512-Yb569su456XNx5BsH/Vyem7xD6g/y9iLmLUzRKM1a/dhU/D7HqqvkAG72znulXlMXztbV0iiu9O5AL8K98TzZQ==", + "dependencies": { + "make-synchronized": "^0.2.8" + }, + "funding": { + "url": "https://github.com/prettier/prettier-synchronized?sponsor=1" + }, + "peerDependencies": { + "prettier": "*" + } + }, + "node_modules/@primer/primitives": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-9.1.1.tgz", + "integrity": "sha512-c8PjLIG+houvCRg9bKza3gj/VoM2QZcN7TqYRa4dl5ZYd1A+BOSvAenjGhVVK23ws8uZSVPYDuvdQk1PO1jm1A==", + "dependencies": { + "@prettier/sync": "^0.5.2", + "prettier": "3.3" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.20.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", @@ -13428,6 +13452,14 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/make-synchronized": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/make-synchronized/-/make-synchronized-0.2.9.tgz", + "integrity": "sha512-4wczOs8SLuEdpEvp3vGo83wh8rjJ78UsIk7DIX5fxdfmfMJGog4bQzxfvOwq7Q3yCHLC4jp1urPHIxRS/A93gA==", + "funding": { + "url": "https://github.com/fisker/make-synchronized?sponsor=1" + } + }, "node_modules/map-or-similar": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", @@ -15687,7 +15719,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" diff --git a/webapp/package.json b/webapp/package.json index bad4e950..207219bc 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -28,6 +28,7 @@ "@angular/platform-browser": "18.2.1", "@angular/platform-browser-dynamic": "18.2.1", "@angular/router": "18.2.1", + "@primer/primitives": "^9.1.1", "@tanstack/angular-query-devtools-experimental": "5.52.0", "@tanstack/angular-query-experimental": "5.52.0", "autoprefixer": "10.4.20", diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.service.ts b/webapp/src/app/components/theme-switcher/theme-switcher.service.ts index 40d58eb2..089f5d50 100644 --- a/webapp/src/app/components/theme-switcher/theme-switcher.service.ts +++ b/webapp/src/app/components/theme-switcher/theme-switcher.service.ts @@ -24,12 +24,14 @@ export class ThemeSwitcherService { this.currentTheme.set(AppTheme.LIGHT); this.setToLocalStorage(AppTheme.LIGHT); this.removeClassFromHtml('dark'); + document.documentElement.setAttribute('data-color-mode', 'light'); } setDarkTheme() { this.currentTheme.set(AppTheme.DARK); this.setToLocalStorage(AppTheme.DARK); this.addClassToHtml('dark'); + document.documentElement.setAttribute('data-color-mode', 'dark'); } setSystemTheme() { @@ -42,6 +44,8 @@ export class ThemeSwitcherService { } else { this.removeClassFromHtml('dark'); } + + document.documentElement.setAttribute('data-color-mode', 'auto'); } private addClassToHtml(className: string) { diff --git a/webapp/src/index.html b/webapp/src/index.html index 53ba96d1..7ee67582 100644 --- a/webapp/src/index.html +++ b/webapp/src/index.html @@ -1,5 +1,5 @@ - + Hephaestus @@ -22,10 +22,12 @@ if (theme === 'dark') { document.documentElement.classList.add('dark'); } + document.documentElement.setAttribute('data-color-mode', theme); } else { if (browserDark) { document.documentElement.classList.add('dark'); } + document.documentElement.setAttribute('data-color-mode', browserDark ? 'dark' : 'light'); localStorage.setItem('theme', browserDark ? 'dark' : 'light'); } diff --git a/webapp/src/styles.css b/webapp/src/styles.css index 00b08e39..17efd71e 100644 --- a/webapp/src/styles.css +++ b/webapp/src/styles.css @@ -1,3 +1,7 @@ +/* GitHub Primer CSS */ +@import '@primer/primitives/dist/css/functional/themes/light.css'; +@import '@primer/primitives/dist/css/functional/themes/dark.css'; + @tailwind base; @tailwind components; @tailwind utilities; diff --git a/webapp/tailwind.config.ts b/webapp/tailwind.config.ts index aec9d229..9f8f6874 100644 --- a/webapp/tailwind.config.ts +++ b/webapp/tailwind.config.ts @@ -50,6 +50,82 @@ const config = { DEFAULT: "hsl(var(--card))", foreground: "hsl(var(--card-foreground))", }, + github: { + foreground: "var(--fgColor-default)", + background: "var(--bgColor-default)", + muted: { + DEFAULT: "var(--bgColor-muted)", + foreground: "var(--fgColor-muted)", + }, + onEmphasis: { + DEFAULT: "var(--bgColor-emphasis)", + foreground: "var(--fgColor-onEmphasis)", + }, + onInverse: { + DEFAULT: "var(--bgColor-inverse)", + foreground: "var(--fgColor-onInverse)", + }, + white: { + DEFAULT: "var(--bgColor-white)", + foreground: "var(--fgColor-white)", + }, + black: { + DEFAULT: "var(--bgColor-black)", + foreground: "var(--fgColor-black)", + }, + disabled: { + DEFAULT: "var(--bgColor-disabled)", + foreground: "var(--fgColor-disabled)", + }, + link: { + DEFAULT: "var(--bgColor-link)", + foreground: "var(--fgColor-link)", + }, + neutral: { + DEFAULT: "var(--bgColor-neutral)", + foreground: "var(--fgColor-neutral)", + }, + accent: { + DEFAULT: "var(--bgColor-accent)", + foreground: "var(--fgColor-accent)", + }, + success: { + DEFAULT: "var(--bgColor-success)", + foreground: "var(--fgColor-success)", + }, + open: { + DEFAULT: "var(--bgColor-open)", + foreground: "var(--fgColor-open)", + }, + attention: { + DEFAULT: "var(--bgColor-attention)", + foreground: "var(--fgColor-attention)", + }, + severe: { + DEFAULT: "var(--bgColor-severe)", + foreground: "var(--fgColor-severe)", + }, + danger: { + DEFAULT: "var(--bgColor-danger)", + foreground: "var(--fgColor-danger)", + }, + closed: { + DEFAULT: "var(--bgColor-closed)", + foreground: "var(--fgColor-closed)", + }, + done: { + DEFAULT: "var(--bgColor-done)", + foreground: "var(--fgColor-done)", + }, + upsell: { + DEFAULT: "var(--bgColor-upsell)", + foreground: "var(--fgColor-upsell)", + }, + sponsors: { + DEFAULT: "var(--bgColor-sponsors)", + foreground: "var(--fgColor-sponsors)", + }, + }, }, borderRadius: { lg: "var(--radius)", @@ -75,4 +151,4 @@ const config = { plugins: [require("tailwindcss-animate")], } satisfies Config -export default config \ No newline at end of file +export default config From c0890c84bb139fe9783e547ea328d061a548ab23 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 15 Sep 2024 16:52:25 +0200 Subject: [PATCH 2/2] improve icons and add GitHub icons --- webapp/package-lock.json | 25 ++++++++++++++++++- webapp/package.json | 4 ++- webapp/src/app/app.component.html | 2 +- webapp/src/app/app.component.ts | 4 ++- webapp/src/app/app.config.ts | 4 +-- .../leaderboard/leaderboard.component.html | 14 +++++------ .../leaderboard/leaderboard.component.ts | 13 +++++----- .../theme-switcher.component.html | 2 +- .../theme-switcher.component.ts | 5 +++- .../theme-switcher/theme-switcher.stories.ts | 3 +-- .../PullRequestApprovedIcon.component.ts | 15 ----------- ...llRequestChangesRequestedIcon.component.ts | 15 ----------- .../icons/PullRequestCommentIcon.component.ts | 15 ----------- 13 files changed, 52 insertions(+), 69 deletions(-) delete mode 100644 webapp/src/app/ui/icons/PullRequestApprovedIcon.component.ts delete mode 100644 webapp/src/app/ui/icons/PullRequestChangesRequestedIcon.component.ts delete mode 100644 webapp/src/app/ui/icons/PullRequestCommentIcon.component.ts diff --git a/webapp/package-lock.json b/webapp/package-lock.json index eafc5a17..42280e4f 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -16,7 +16,9 @@ "@angular/platform-browser": "18.2.1", "@angular/platform-browser-dynamic": "18.2.1", "@angular/router": "18.2.1", - "@primer/primitives": "^9.1.1", + "@ng-icons/core": "29.5.0", + "@ng-icons/octicons": "29.5.0", + "@primer/primitives": "9.1.1", "@tanstack/angular-query-devtools-experimental": "5.52.0", "@tanstack/angular-query-experimental": "5.52.0", "autoprefixer": "10.4.20", @@ -4085,6 +4087,27 @@ "win32" ] }, + "node_modules/@ng-icons/core": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@ng-icons/core/-/core-29.5.0.tgz", + "integrity": "sha512-MpM8I/7uzUC7SKRt29d4ByCpKjk8sXTlOiLuBCTHG1uyI14jUZdpyhBwpCpGKpkqqmfxDkvN848hjhFiOKlBuA==", + "dependencies": { + "tslib": "^2.2.0" + }, + "peerDependencies": { + "@angular/common": ">=18.0.0", + "@angular/core": ">=18.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@ng-icons/octicons": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@ng-icons/octicons/-/octicons-29.5.0.tgz", + "integrity": "sha512-z9EVYqmSCxVkeLF9wp0lruWCZP1eN0UYNYLtjNs38f3nzx3x0+eME8+Ek1iZaEVf9MnMubT0l1lJjupw+rWmKg==", + "dependencies": { + "tslib": "^2.2.0" + } + }, "node_modules/@ngtools/webpack": { "version": "18.2.1", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 207219bc..cb31cc2e 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -28,7 +28,9 @@ "@angular/platform-browser": "18.2.1", "@angular/platform-browser-dynamic": "18.2.1", "@angular/router": "18.2.1", - "@primer/primitives": "^9.1.1", + "@ng-icons/core": "29.5.0", + "@ng-icons/octicons": "29.5.0", + "@primer/primitives": "9.1.1", "@tanstack/angular-query-devtools-experimental": "5.52.0", "@tanstack/angular-query-experimental": "5.52.0", "autoprefixer": "10.4.20", diff --git a/webapp/src/app/app.component.html b/webapp/src/app/app.component.html index 7835f94e..d71dcc41 100644 --- a/webapp/src/app/app.component.html +++ b/webapp/src/app/app.component.html @@ -4,7 +4,7 @@
- + Hephaestus diff --git a/webapp/src/app/app.component.ts b/webapp/src/app/app.component.ts index 647cf15a..41c404cf 100644 --- a/webapp/src/app/app.component.ts +++ b/webapp/src/app/app.component.ts @@ -1,7 +1,7 @@ import { Component, isDevMode } from '@angular/core'; import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'; import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'; -import { LucideAngularModule } from 'lucide-angular'; +import { LucideAngularModule, Hammer } from 'lucide-angular'; import { ThemeSwitcherComponent } from './components/theme-switcher/theme-switcher.component'; @Component({ @@ -12,6 +12,8 @@ import { ThemeSwitcherComponent } from './components/theme-switcher/theme-switch styles: [] }) export class AppComponent { + protected Hammer = Hammer; + title = 'Hephaestus'; isDevMode() { diff --git a/webapp/src/app/app.config.ts b/webapp/src/app/app.config.ts index a0e8b341..eb96f70b 100644 --- a/webapp/src/app/app.config.ts +++ b/webapp/src/app/app.config.ts @@ -1,9 +1,8 @@ -import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { APP_INITIALIZER, ApplicationConfig, provideExperimentalZonelessChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { provideAngularQuery, QueryClient } from '@tanstack/angular-query-experimental'; -import { LucideAngularModule, Home, Sun, Moon, Hammer } from 'lucide-angular'; import { environment } from 'environments/environment'; import { BASE_PATH } from 'app/core/modules/openapi'; import { routes } from 'app/app.routes'; @@ -22,7 +21,6 @@ export const appConfig: ApplicationConfig = { provideAngularQuery(new QueryClient()), provideHttpClient(withInterceptorsFromDi()), provideAnimationsAsync(), - importProvidersFrom(LucideAngularModule.pick({ Home, Sun, Moon, Hammer })), { provide: BASE_PATH, useValue: environment.serverUrl }, { provide: APP_INITIALIZER, useFactory: initializeAnalytics, multi: true, deps: [AnalyticsService] } ] diff --git a/webapp/src/app/components/leaderboard/leaderboard.component.html b/webapp/src/app/components/leaderboard/leaderboard.component.html index 8e854a45..04815e8a 100644 --- a/webapp/src/app/components/leaderboard/leaderboard.component.html +++ b/webapp/src/app/components/leaderboard/leaderboard.component.html @@ -28,22 +28,22 @@

Artemis Leaderboard

{{ entry.score }} - + @if (entry.changesRequested && entry.changesRequested > 0) { -
- +
+ {{ entry.changesRequested }}
} @if (entry.approvals && entry.approvals > 0) { -
- +
+ {{ entry.approvals }}
} @if (entry.comments && entry.comments > 0) { -
- +
+ {{ entry.comments }}
} diff --git a/webapp/src/app/components/leaderboard/leaderboard.component.ts b/webapp/src/app/components/leaderboard/leaderboard.component.ts index 08ddbe8a..24757f6f 100644 --- a/webapp/src/app/components/leaderboard/leaderboard.component.ts +++ b/webapp/src/app/components/leaderboard/leaderboard.component.ts @@ -1,9 +1,8 @@ import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core'; import { injectQuery } from '@tanstack/angular-query-experimental'; +import { NgIconComponent } from '@ng-icons/core'; +import { octFileDiff, octCheck, octComment } from '@ng-icons/octicons'; import { LeaderboardEntry, LeaderboardService } from 'app/core/modules/openapi'; -import { PullRequestApprovedIconComponent } from 'app/ui/icons/PullRequestApprovedIcon.component'; -import { PullRequestChangesRequestedIconComponent } from 'app/ui/icons/PullRequestChangesRequestedIcon.component'; -import { PullRequestCommentIconComponent } from 'app/ui/icons/PullRequestCommentIcon.component'; import { TableBodyDirective } from 'app/ui/table/table-body.directive'; import { TableCaptionDirective } from 'app/ui/table/table-caption.directive'; import { TableCellDirective } from 'app/ui/table/table-cell.directive'; @@ -119,14 +118,16 @@ const defaultData: LeaderboardEntry[] = [ TableHeaderDirective, TableHeadDirective, TableRowDirective, - PullRequestChangesRequestedIconComponent, - PullRequestApprovedIconComponent, - PullRequestCommentIconComponent + NgIconComponent ], templateUrl: './leaderboard.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class LeaderboardComponent { + protected octFileDiff = octFileDiff; + protected octCheck = octCheck; + protected octComment = octComment; + leaderboardService = inject(LeaderboardService); query = injectQuery(() => ({ diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.component.html b/webapp/src/app/components/theme-switcher/theme-switcher.component.html index f2ca7226..95c8ccb0 100644 --- a/webapp/src/app/components/theme-switcher/theme-switcher.component.html +++ b/webapp/src/app/components/theme-switcher/theme-switcher.component.html @@ -1,5 +1,5 @@
- +
diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.component.ts b/webapp/src/app/components/theme-switcher/theme-switcher.component.ts index 86e285b3..fc7722fc 100644 --- a/webapp/src/app/components/theme-switcher/theme-switcher.component.ts +++ b/webapp/src/app/components/theme-switcher/theme-switcher.component.ts @@ -1,5 +1,5 @@ import { Component, inject } from '@angular/core'; -import { LucideAngularModule } from 'lucide-angular'; +import { LucideAngularModule, Sun, Moon } from 'lucide-angular'; import { ButtonComponent } from 'app/ui/button/button.component'; import { AppTheme, ThemeSwitcherService } from './theme-switcher.service'; import { animate, state, style, transition, trigger } from '@angular/animations'; @@ -20,6 +20,9 @@ import { animate, state, style, transition, trigger } from '@angular/animations' export class ThemeSwitcherComponent { themeSwitcherService = inject(ThemeSwitcherService); + protected Sun = Sun; + protected Moon = Moon; + toggleTheme() { if (this.themeSwitcherService.currentTheme() === AppTheme.DARK) { this.themeSwitcherService.setLightTheme(); diff --git a/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts b/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts index 527dde1c..3f00cdb2 100644 --- a/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts +++ b/webapp/src/app/components/theme-switcher/theme-switcher.stories.ts @@ -1,5 +1,4 @@ import { moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; -import { LucideAngularModule, Sun, Moon } from 'lucide-angular'; import { ThemeSwitcherComponent } from './theme-switcher.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -10,7 +9,7 @@ const meta: Meta = { tags: ['autodocs'], decorators: [ moduleMetadata({ - imports: [LucideAngularModule.pick({ Sun, Moon }), BrowserAnimationsModule] + imports: [BrowserAnimationsModule] }) ] }; diff --git a/webapp/src/app/ui/icons/PullRequestApprovedIcon.component.ts b/webapp/src/app/ui/icons/PullRequestApprovedIcon.component.ts deleted file mode 100644 index 42fd5286..00000000 --- a/webapp/src/app/ui/icons/PullRequestApprovedIcon.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-icon-pull-request-approved', - template: ` - - - - `, - standalone: true -}) -export class PullRequestApprovedIconComponent {} diff --git a/webapp/src/app/ui/icons/PullRequestChangesRequestedIcon.component.ts b/webapp/src/app/ui/icons/PullRequestChangesRequestedIcon.component.ts deleted file mode 100644 index 5e729e2f..00000000 --- a/webapp/src/app/ui/icons/PullRequestChangesRequestedIcon.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-icon-pull-request-changes-requested', - template: ` - - - - `, - standalone: true -}) -export class PullRequestChangesRequestedIconComponent {} diff --git a/webapp/src/app/ui/icons/PullRequestCommentIcon.component.ts b/webapp/src/app/ui/icons/PullRequestCommentIcon.component.ts deleted file mode 100644 index 919cedcb..00000000 --- a/webapp/src/app/ui/icons/PullRequestCommentIcon.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-icon-pull-request-comment', - template: ` - - - - `, - standalone: true -}) -export class PullRequestCommentIconComponent {}