Skip to content

Commit

Permalink
feat: Removed config.json and related things (#1319)
Browse files Browse the repository at this point in the history
closes #841 

MIGRATION REQUIRED App title name needs to be moved to config in database
  • Loading branch information
TheSlimvReal authored Jul 28, 2022
1 parent 08222ce commit ca3704a
Show file tree
Hide file tree
Showing 39 changed files with 320 additions and 497 deletions.
36 changes: 0 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,6 @@ You can directly run the system using Docker.
More information in our [Aam-Digital/ndb-setup repository](https://github.com/Aam-Digital/ndb-setup/).
In that case you do not have to clone this repository and install all the dependencies as everything is packaged into the docker image already.

## Configuration
The custom configuration for your service instance is set in the `assets/config.json` file.
You can copy the `assets/config.default.json` as a starting point.

### Nextcloud (webdav) Integration
You can integrate Aam Digital with an existing Nextcloud server to allow users to update photos on their own.
To avoid CORS issues the webdav URL in your _config.json_ should be a relative URL
in combination with a reverse-proxy that is forwarding to the actual Nextcloud server address:

_assets/config.json:_
```
"webdav": {
"remote_url": "nextcloud/"
}
```

_proxy.conf.json_ (for local development):
```
"/nextcloud": {
"target": "https://<your-nextcloud-server>/remote.php/webdav",
"secure": true,
"changeOrigin": true,
"pathRewrite": {
"^/nextcloud": ""
}
}
```

_docker-compose.yml_ (for production server):
```
environment:
WEBDAV_URL: https://<your-nextcloud-server>/remote.php/webdav
```

-----

# Development

## Setup
Expand Down
11 changes: 5 additions & 6 deletions build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# This docker image can be used to run the application locally.
# To use it only Docker needs to be installed locally
# Run the following commands from the root folder to build, run and kill the application
# >> docker build -f build/Dockerfile -t aam/digital:latest .
# >> docker run -p=80:80 aam/digital:latest
# >> docker kill aam-digital
# >> docker build -f build/Dockerfile -t aam-digital .
# >> docker run -p=80:80 aam-digital
FROM node:16.14.2-alpine3.15 as builder
WORKDIR /app

Expand Down Expand Up @@ -67,10 +66,10 @@ COPY ./build/default.conf /etc/nginx/templates/default.conf
COPY --from=builder /app/dist/ /usr/share/nginx/html
# The port on which the app will run in the Docker container
ENV PORT=80
# The url to the webdav server
ENV WEBDAV_URL="http://localhost"
# The url to the CouchDB database
ENV COUCHDB_URL="http://localhost"
# Whether the app should be started in demo mode. Everything else then "true" is considered as "false".
ENV DEMO="true"
# variables are inserted into the nginx config
CMD envsubst '$$PORT $$WEBDAV_URL $$COUCHDB_URL' < /etc/nginx/templates/default.conf > /etc/nginx/conf.d/default.conf &&\
CMD envsubst '$$PORT $$COUCHDB_URL $$DEMO' < /etc/nginx/templates/default.conf > /etc/nginx/conf.d/default.conf &&\
nginx -g 'daemon off;'
16 changes: 16 additions & 0 deletions build/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@ server {
try_files $uri =404;
}

# Files should be directly accessed
location ~* \.[a-zA-Z]+$ {
try_files $uri =404;
}

location / {
# Demo mode params are added to URL when not yet present and DEMO is set to true
if ($arg_demo_mode != "true") {
set $demo "${DEMO}";
}
if ($demo = "true") {
# This first part is required because Heroku does some internal redirects which break the rewrite otherwise
# This does not work in localhost as it enforces HTTPS
rewrite ^ https://$http_host$uri?demo_mode=true&session_type=mock permanent;
}

index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
Expand All @@ -27,6 +42,7 @@ server {
root /usr/share/nginx/html;
}

# The proxy path should be the same as in AppSettings.DB_PROXY_PREFIX
location ^~ /db {
rewrite /db/(.*) /$1 break;
proxy_pass ${COUCHDB_URL};
Expand Down
9 changes: 0 additions & 9 deletions proxy.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,5 @@
"pathRewrite": {
"/db": ""
}
},
"/nextcloud": {
"target": "https://nextcloud.aam-digital.com/remote.php/webdav",
"secure": true,
"logLevel": "debug",
"changeOrigin": true,
"pathRewrite": {
"^/nextcloud": ""
}
}
}
40 changes: 14 additions & 26 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,10 @@ import {
fakeAsync,
flush,
TestBed,
tick,
waitForAsync,
} from "@angular/core/testing";
import { AppComponent } from "./app.component";
import { AppModule } from "./app.module";
import { AppConfig } from "./core/app-config/app-config";
import { IAppConfig } from "./core/app-config/app-config.model";
import { Config } from "./core/config/config";
import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config";
import { environment } from "../environments/environment";
Expand All @@ -47,28 +44,19 @@ describe("AppComponent", () => {
let fixture: ComponentFixture<AppComponent>;
let entityUpdates: Subject<UpdatedEntity<Config>>;

const mockAppSettings: IAppConfig = {
database: { name: "", remote_url: "" },
session_type: SessionType.local,
demo_mode: false,
site_name: "",
};
beforeEach(waitForAsync(() => {
environment.session_type = SessionType.mock;
const entityMapper = mockEntityMapper();
entityUpdates = new Subject();
spyOn(entityMapper, "receiveUpdates").and.returnValue(entityUpdates);

beforeEach(
waitForAsync(() => {
AppConfig.settings = mockAppSettings;
const entityMapper = mockEntityMapper();
entityUpdates = new Subject();
spyOn(entityMapper, "receiveUpdates").and.returnValue(entityUpdates);
TestBed.configureTestingModule({
imports: [AppModule, HttpClientTestingModule],
providers: [{ provide: EntityMapperService, useValue: entityMapper }],
}).compileComponents();

TestBed.configureTestingModule({
imports: [AppModule, HttpClientTestingModule],
providers: [{ provide: EntityMapperService, useValue: entityMapper }],
}).compileComponents();

spyOn(TestBed.inject(EntityRegistry), "add"); // Prevent error with duplicate registration
})
);
spyOn(TestBed.inject(EntityRegistry), "add"); // Prevent error with duplicate registration
}));

function createComponent() {
fixture = TestBed.createComponent(AppComponent);
Expand Down Expand Up @@ -101,7 +89,7 @@ describe("AppComponent", () => {
window["_paq"] = [];

createComponent();
tick();
flush();

expect(startTrackingSpy).toHaveBeenCalledTimes(1);
expect(window["_paq"]).toContain([
Expand All @@ -115,13 +103,13 @@ describe("AppComponent", () => {
it("published the demo data", fakeAsync(() => {
const demoDataService = TestBed.inject(DemoDataService);
spyOn(demoDataService, "publishDemoData").and.callThrough();
AppConfig.settings.demo_mode = true;
environment.demo_mode = true;

createComponent();
flush();
discardPeriodicTasks();

expect(demoDataService.publishDemoData).toHaveBeenCalled();
AppConfig.settings.demo_mode = false;
environment.demo_mode = false;
}));
});
3 changes: 1 addition & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { environment } from "../environments/environment";
import { Child } from "./child-dev-project/children/model/child";
import { School } from "./child-dev-project/schools/model/school";
import { DemoDataInitializerService } from "./core/demo-data/demo-data-initializer.service";
import { AppConfig } from "./core/app-config/app-config";
import { LoginState } from "./core/session/session-states/login-state.enum";
import { LoggingService } from "./core/logging/logging.service";
import { EntityRegistry } from "./core/entity/database-entity.decorator";
Expand Down Expand Up @@ -90,7 +89,7 @@ export class AppComponent {
this.analyticsService.init();
}

if (AppConfig.settings.demo_mode) {
if (environment.demo_mode) {
await this.demoDataInitializer.run();
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import {
DEFAULT_LANGUAGE,
LANGUAGE_LOCAL_STORAGE_KEY,
} from "./core/language/language-statics";
import { AppSettings } from "./core/app-config/app-settings";

/**
* Main entry point of the application.
Expand Down Expand Up @@ -177,6 +178,7 @@ import {
})
export class AppModule {
constructor(icons: FaIconLibrary) {
AppSettings.initRuntimeSettings();
icons.addIconPacks(fas, far);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("ChildPhotoService", () => {
expect(service).toBeTruthy();
});

it("should getFile default if no webdav connection", async () => {
it("should getFile default", async () => {
const testChild = new Child("1");
const actualImage = await service.getImage(testChild);
expect(actualImage).toBe(DEFAULT_IMG);
Expand Down
29 changes: 12 additions & 17 deletions src/app/core/admin/admin/admin.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ <h1>Administration & Configuration</h1>
you know what you are doing.
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Utility Functions</h2>
<p fxLayoutGap="12px">
<button
Expand All @@ -17,8 +17,8 @@ <h2>Utility Functions</h2>
</button>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Backup</h2>
<p>
<button
Expand All @@ -42,8 +42,8 @@ <h2>Backup</h2>
/>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Export</h2>
<p>
<button
Expand All @@ -54,8 +54,8 @@ <h2>Export</h2>
</button>
&nbsp;
</p>
<br />
<hr />
<br/>
<hr/>
<h2>Application Configuration</h2>
<p>
<button
Expand All @@ -79,13 +79,8 @@ <h2>Application Configuration</h2>
/>
</p>

<br />
<hr />
<h2>AppConfig</h2>
<p>{{ appConfig | json }}</p>

<br />
<hr />
<br/>
<hr/>
<h2>Debug the PouchDB</h2>
<p>
<button (click)="debugDatabase()" mat-stroked-button>
Expand All @@ -101,8 +96,8 @@ <h2>Debug the PouchDB</h2>
</button>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Alert Log</h2>
<table aria-label="Table showing alerts">
<tr *ngFor="let alert of alerts.reverse()">
Expand Down
44 changes: 17 additions & 27 deletions src/app/core/admin/admin/admin.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import {
} from "@angular/core/testing";
import { AdminComponent } from "./admin.component";
import { BackupService } from "../services/backup.service";
import { AppConfig } from "../../app-config/app-config";
import { ConfigService } from "../../config/config.service";
import { ConfirmationDialogService } from "../../confirmation-dialog/confirmation-dialog.service";
import { SessionType } from "../../session/session-type";
import { AdminModule } from "../admin.module";
import { MockedTestingModule } from "../../../utils/mocked-testing.module";
import { environment } from "../../../../environments/environment";

describe("AdminComponent", () => {
let component: AdminComponent;
Expand All @@ -31,9 +31,8 @@ describe("AdminComponent", () => {
"importJson",
]);

const confirmationDialogMock = jasmine.createSpyObj<ConfirmationDialogService>(
["getConfirmation"]
);
const confirmationDialogMock =
jasmine.createSpyObj<ConfirmationDialogService>(["getConfirmation"]);

const tmplink: jasmine.SpyObj<HTMLAnchorElement> = jasmine.createSpyObj(
"mockLink",
Expand All @@ -53,30 +52,21 @@ describe("AdminComponent", () => {
return mockFileReader;
}

beforeEach(
waitForAsync(() => {
AppConfig.settings = {
site_name: "",
session_type: SessionType.mock,
database: {
name: "unit-tests",
remote_url: "",
beforeEach(waitForAsync(() => {
environment.session_type = SessionType.mock;

TestBed.configureTestingModule({
imports: [AdminModule, MockedTestingModule.withState()],
providers: [
{ provide: BackupService, useValue: mockBackupService },
{ provide: ConfigService, useValue: mockConfigService },
{
provide: ConfirmationDialogService,
useValue: confirmationDialogMock,
},
};

TestBed.configureTestingModule({
imports: [AdminModule, MockedTestingModule.withState()],
providers: [
{ provide: BackupService, useValue: mockBackupService },
{ provide: ConfigService, useValue: mockConfigService },
{
provide: ConfirmationDialogService,
useValue: confirmationDialogMock,
},
],
}).compileComponents();
})
);
],
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AdminComponent);
Expand Down
4 changes: 0 additions & 4 deletions src/app/core/admin/admin/admin.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, OnInit } from "@angular/core";
import { AppConfig } from "../../app-config/app-config";
import { AlertService } from "../../alerts/alert.service";
import { Alert } from "../../alerts/alert";
import { BackupService } from "../services/backup.service";
Expand All @@ -23,9 +22,6 @@ import { Database } from "../../database/database";
styleUrls: ["./admin.component.scss"],
})
export class AdminComponent implements OnInit {
/** app-wide configuration */
appConfig = AppConfig.settings;

/** all alerts */
alerts: Alert[];

Expand Down
Loading

0 comments on commit ca3704a

Please sign in to comment.