Skip to content

Commit

Permalink
Merge pull request #55 from CentreForDigitalHumanities/feature/bulma-1
Browse files Browse the repository at this point in the history
Feature/bulma 1
  • Loading branch information
oktaal authored Oct 30, 2024
2 parents 1a30452 + b7d211b commit 8de2764
Show file tree
Hide file tree
Showing 33 changed files with 509 additions and 94 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
python-version: ['3.8', '3.9']
node-version: ['18.x', '20.x']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
Expand All @@ -66,13 +66,18 @@ jobs:
PGUSER: dighum_pro
PGPASSWORD: dighum_pro
run: |
# need to be able to create an initial commit
git config --global user.name 'Agent Smith'
git config --global user.email 'agent-smith@hum.uu.nl'
cookiecutter . --no-input
cd dighum_pro
cat bootstrap.log
yarn
yarn django migrate
# start the backend first for the SSR
yarn start-back-p &
sleep 10
yarn static-p
find static
yarn start-back-p &
chromedriver --version
yarn test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.env/
.env/
.DS_Store
2 changes: 1 addition & 1 deletion cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"app_prefix": "dh",
"description": "{{cookiecutter.project_title}} will humanize all your digits!",
"author": "Research Software Lab, Centre for Digital Humanities, Utrecht University",
"author_url": "https://cdh.uu.nl/centre-for-digital-humanities/research-software-lab/",
"author_url": "https://cdh.uu.nl/about/research-software-lab/",
"origin": "github:CentreForDigitalHumanities/{{cookiecutter.slug}}",
"database_name": "{{cookiecutter.slug}}",
"database_user": "{{cookiecutter.slug}}",
Expand Down
4 changes: 3 additions & 1 deletion {{cookiecutter.slug}}/.github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ jobs:
cat bootstrap_ci.txt | python bootstrap.py
yarn
yarn django migrate
# start the backend first for the SSR
yarn start-back-p &
sleep 10
yarn static-p
find static
yarn start-back-p &
chromedriver --version
yarn test
2 changes: 2 additions & 0 deletions {{cookiecutter.slug}}/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.slug}}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

## Getting started

{{cookiecutter.project_title}} is a web application: it can be acessed using a web browser.
{{cookiecutter.project_title}} is a web application: it can be accessed using a web browser.

*If you are hosting {{cookiecutter.project_title}} anywhere, provide a URL and any additional info.*

Expand Down
2 changes: 2 additions & 0 deletions {{cookiecutter.slug}}/frontend.angular/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Run `ng generate component component-name` to generate a new component. You can

Run `yarn build` to build the project. The build artifacts will be stored in the `dist/` directory.

With SSR (Server Side Rendering) all the routes will be pre-compiled. Because of this the backend server should already be running before building the frontend!

## Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
Expand Down
31 changes: 31 additions & 0 deletions {{cookiecutter.slug}}/frontend.angular/angular.overwrite.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,37 @@
"src/favicon.png",
"src/favicon.svg",
"src/assets"
],
"styles": [
"src/styles.scss",
{
"input": "src/dark.scss",
"bundleName": "dark",
"inject": false
},
{
"input": "src/light.scss",
"bundleName": "light",
"inject": false
}
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"sourceMap": true
},
{% set comma = joiner(",") %}
{%- for loc in localizations %}
{%- set code, name = loc.split(':') %}
Expand All @@ -50,6 +78,9 @@
"defaultConfiguration": "production"
},
"serve": {
"options": {
"proxyConfig": "../proxy.conf.json"
},
"configurations": {
{% set comma = joiner(",") %}
{%- for loc in localizations %}
Expand Down
7 changes: 3 additions & 4 deletions {{cookiecutter.slug}}/frontend.angular/package.overwrite.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"build": "ng build --base-href=/static/ --localize",
"i18n": "ng extract-i18n --output-path locale",
"preserve": "yarn prebuild",
"serve": "ng serve --proxy-config ../proxy.conf.json",
"serve": "ng serve",
"start": "yarn serve",
{% set localizations = cookiecutter.localizations.split(',') %}
{%- for loc in localizations %}
{%- set code, name = loc.split(':') %}
"serve:{{code}}": "ng serve --proxy-config ../proxy.conf.json --configuration={{code}}",
"serve:{{code}}": "ng serve --configuration={{code}}",
{%- endfor %}
"stop": "lsof -t -i tcp:{{cookiecutter.frontend_port}} | xargs kill -9 || echo \"not running\"",
"pretest": "yarn prebuild",
Expand All @@ -25,9 +25,8 @@
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@ngrx/effects": "^17.2.0",
"@ngrx/store": "^17.2.0",
"bulma": "^0.9.1",
"bulma": "^1.0.1",
"colors": "^1.4.0",
"primeicons": "^7.0.0",
"primeng": "^17.18.0"
},
"devDependencies": {
Expand Down
21 changes: 20 additions & 1 deletion {{cookiecutter.slug}}/frontend.angular/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Component } from '@angular/core';
import { Component, Inject, afterRender } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { MenuComponent } from './menu/menu.component';
import { FooterComponent } from './footer/footer.component';
import { DarkModeService } from './services/dark-mode.service';

@Component({
selector: '{{cookiecutter.app_prefix}}-root',
Expand All @@ -12,4 +14,21 @@ import { FooterComponent } from './footer/footer.component';
})
export class AppComponent {
title = '{{cookiecutter.project_title}}';

constructor(@Inject(DOCUMENT) private document: Document, private darkModeService: DarkModeService) {
// Using the DOM API to only render on the browser instead of on the server
afterRender(() => {
const style = this.document.createElement('link');
style.rel = 'stylesheet';
this.document.head.append(style);

this.darkModeService.theme$.subscribe(theme => {
this.document.documentElement.classList.remove(theme === 'dark' ? 'theme-light' : 'theme-dark');
this.document.documentElement.classList.add('theme-' + theme);

style.href = `${theme}.css`;
});
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
import { BACKEND_URL_OVERRIDE, appConfig } from './app.config';

const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(),
{ provide: BACKEND_URL_OVERRIDE, useValue: 'http://localhost:{{cookiecutter.backend_port}}/api/' }
]
};

export const config = mergeApplicationConfig(appConfig, serverConfig);
24 changes: 18 additions & 6 deletions {{cookiecutter.slug}}/frontend.angular/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { ApplicationConfig, InjectionToken, provideZoneChangeDetection } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { provideHttpClient, withXsrfConfiguration } from '@angular/common/http';
import { provideHttpClient, withFetch, withXsrfConfiguration } from '@angular/common/http';
import { provideClientHydration } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

/**
* because proxy doesn't work for SSR, support a wonky workaround
* by manually specifying the URL where the backend is running
* https://github.com/angular/angular-cli/issues/27144
* By default it is empty, because in the browser this isn't needed
*/
export const BACKEND_URL_OVERRIDE = new InjectionToken<string | null>('BackendUrl', {
factory: () => null
});

export const appConfig: ApplicationConfig = {
providers: [
provideAnimations(),
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideClientHydration(),
provideHttpClient(withXsrfConfiguration({
cookieName: 'csrftoken',
headerName: 'X-CSRFToken'
})),
provideHttpClient(
withFetch(),
withXsrfConfiguration({
cookieName: 'csrftoken',
headerName: 'X-CSRFToken'
})),
// The language is used as the base_path for finding the right
// static-files. For example /nl/static/main.js
// However the routing is done from a base path starting from
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<p class="control">
@if (dark) {
<a class="button" title="Switch to light mode" i18n-title (click)="toggle()">
<span class="icon">
<fa-icon [icon]="faMoon"></fa-icon>
</span>
</a>
}
@else {
<a class="button" title="Switch to dark mode" i18n-title (click)="toggle()">
<span class="icon">
<fa-icon [icon]="faSun"></fa-icon>
</span>
</a>
}
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DarkModeToggleComponent } from './dark-mode-toggle.component';

describe('DarkModeToggleComponent', () => {
let component: DarkModeToggleComponent;
let fixture: ComponentFixture<DarkModeToggleComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DarkModeToggleComponent]
})
.compileComponents();

fixture = TestBed.createComponent(DarkModeToggleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Component, OnDestroy } from '@angular/core';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { faSun, faMoon } from '@fortawesome/free-solid-svg-icons';
import { Subscription } from 'rxjs';
import { DarkModeService } from '../services/dark-mode.service';

@Component({
selector: '{{cookiecutter.app_prefix}}-dark-mode-toggle',
standalone: true,
imports: [FontAwesomeModule],
templateUrl: './dark-mode-toggle.component.html',
styleUrl: './dark-mode-toggle.component.scss'
})
export class DarkModeToggleComponent implements OnDestroy {
private subscriptions!: Subscription[];
faSun = faSun;
faMoon = faMoon;
dark = false;

constructor(private darkModeService: DarkModeService) {
this.subscriptions = [
this.darkModeService.theme$.subscribe(theme => this.dark = theme === 'dark')];
}

toggle() {
this.darkModeService.toggle();
}

ngOnDestroy(): void {
this.subscriptions.forEach(s => s.unsubscribe());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
<h1 class="subtitle" i18n>{{cookiecutter.project_title}}</h1>
<div class="content">
<p>
<a href="{{cookiecutter.origin.replace('github:', 'https://github.com/')}}" i18n>Source code</a>&nbsp;<ng-container i18n>(BSD 3-Clause License)</ng-container>
<a [href]="environment.sourceUrl" target="_blank" i18n>Source code</a>&nbsp;<ng-container i18n>(BSD 3-Clause License)</ng-container>
</p>
<p>
<em><ng-container i18n>Version: </ng-container><span [title]="environment.buildTime">{{"{{environment.version}}"}}</span>&nbsp;<a [href]="environment.sourceUrl" target="_blank" i18n>(source)</a></em>
<em><ng-container i18n>Version: </ng-container><span>{{"{{environment.version}}"}}</span>&nbsp;(<span [title]="environment.buildTime">{{"{{buildTime}}"}})</span></em>
</p>
</div>
</div>
<div class="column has-text-right-tablet is-narrow">
<a class="lab-logo image" href="https://cdh.uu.nl/centre-for-digital-humanities/research-software-lab/" target="_blank">
<img src="{{"{{environment.assets}}"}}/uu-cdh.svg" alt="Centre for Digital Humanities, Utrecht University" i18n-alt height="100" />
<a class="centre-logo image"
href="https://cdh.uu.nl/about/research-software-lab/" target="_blank">
<img [src]="environment.assets + (dark ? '/uu-cdh-dark.svg' :'/uu-cdh.svg')"
alt="Centre for Digital Humanities, Utrecht University" i18n-alt width="450" height="105" />
</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.lab-logo {
max-width: 400px;
.centre-logo {
width: 450px;
max-width: calc(100vw - 7rem);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import { Component } from '@angular/core';
import { Component, Inject, LOCALE_ID, OnDestroy } from '@angular/core';
import { formatDate } from '@angular/common';
import { Subscription } from 'rxjs';
import { environment } from '../../environments/environment';
import { DarkModeService } from '../services/dark-mode.service';

@Component({
selector: '{{cookiecutter.app_prefix}}-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
standalone: true
})
export class FooterComponent {
export class FooterComponent implements OnDestroy {
environment = environment;
buildTime!: string;
dark = false;
subscriptions!: Subscription[];

constructor() { }
constructor(@Inject(LOCALE_ID) localeId: string, darkModeService: DarkModeService) {
this.buildTime = formatDate(new Date(environment.buildTime), $localize`:@@dateFormat:MMMM dd, yyyy`, localeId);
this.subscriptions = [
darkModeService.theme$.subscribe(theme => this.dark = theme === 'dark')];
}

ngOnDestroy(): void {
this.subscriptions.forEach(s => s.unsubscribe());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
Home
</a>
</div>
<div class="navbar-end" *ngIf="languages">
<div class="navbar-end">
<{{cookiecutter.app_prefix}}-dark-mode-toggle class="navbar-item"></{{cookiecutter.app_prefix}}-dark-mode-toggle>
@if (languages) {
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
<span class="icon">
Expand All @@ -37,6 +39,7 @@
</a>
</div>
</div>
}
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 8de2764

Please sign in to comment.