Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable styles #1953

Merged
merged 70 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
5c77d5b
added button to change styles
TheSlimvReal Aug 1, 2023
121d9c9
added favicon replace
TheSlimvReal Aug 2, 2023
bad6211
removed duplicate providers
TheSlimvReal Aug 2, 2023
5c4fd60
moved settings to own entity and serice
TheSlimvReal Aug 2, 2023
6e041bf
created directive that automatically show a image of an entity
TheSlimvReal Aug 3, 2023
607ae32
using child element to show image
TheSlimvReal Aug 3, 2023
a0f18fa
using component instead of directive
TheSlimvReal Aug 3, 2023
bce9340
using display image component for app logo
TheSlimvReal Aug 3, 2023
4254f6b
icon can be changed
TheSlimvReal Aug 3, 2023
94fc2c7
primary color palette can be changed
TheSlimvReal Aug 4, 2023
eb27683
added option to change font, secondary and warning color
TheSlimvReal Aug 4, 2023
8727e4c
added todos
TheSlimvReal Aug 4, 2023
4fa9b65
removed prototype code
TheSlimvReal Aug 4, 2023
90fc418
Merge remote-tracking branch 'origin/master' into configurable_styles
TheSlimvReal Aug 14, 2023
88ce433
added todo
TheSlimvReal Aug 16, 2023
947f79d
added overwrite for fab button contrast color
TheSlimvReal Aug 22, 2023
f443bb8
added overwrite for progress bar and normal accent buttons
TheSlimvReal Aug 22, 2023
fb63d0e
Merge remote-tracking branch 'origin/master' into configurable_styles
TheSlimvReal Aug 22, 2023
99b29ad
some review adjustments
TheSlimvReal Aug 22, 2023
e6ae8fa
finished comment
TheSlimvReal Aug 22, 2023
d05d781
app logo component has ngIf
TheSlimvReal Aug 22, 2023
370810b
using a fixed ID for site settings
TheSlimvReal Aug 23, 2023
4f5f3d5
file service only listens for removed docs once the sync has been com…
TheSlimvReal Aug 23, 2023
4b55dfa
removed unnecessary blob conversion
TheSlimvReal Aug 23, 2023
615915c
images are only requested if the property has a value
TheSlimvReal Aug 23, 2023
32022dc
Merge remote-tracking branch 'origin/master' into configurable_styles
TheSlimvReal Aug 24, 2023
5a6ec92
fixed style for checkbox checkmark
TheSlimvReal Aug 24, 2023
a1c6747
fixed config for site settings
TheSlimvReal Aug 24, 2023
0cd5052
abstracting latest entity logic to class
TheSlimvReal Aug 24, 2023
22aa9ab
fix: removed migration for configurable enums
TheSlimvReal Aug 24, 2023
5b9076c
Merge branch 'remove_enum_migration' into configurable_styles
TheSlimvReal Aug 24, 2023
3a9bb24
fix: removed migration for configurable enums
TheSlimvReal Aug 24, 2023
65513b2
Merge branch 'remove_enum_migration' into configurable_styles
TheSlimvReal Aug 24, 2023
eeab1fd
fixed testing config service
TheSlimvReal Aug 24, 2023
f223304
using LatestEntity in ability service
TheSlimvReal Aug 24, 2023
f0142d5
fixed tests for analytics service
TheSlimvReal Aug 24, 2023
b7cdeb7
fixed all tests
TheSlimvReal Aug 24, 2023
874609a
Merge branch 'master' into configurable_styles
TheSlimvReal Aug 24, 2023
a18c20e
fix(forms): display label for photo fields
sleidig Aug 24, 2023
a1e8f88
Merge remote-tracking branch 'origin/master' into configurable_styles
TheSlimvReal Aug 28, 2023
6afefbd
favicon is automatically reset if icon is removed
TheSlimvReal Aug 28, 2023
a0efb58
made compression of images configurable
TheSlimvReal Aug 28, 2023
99c015e
added context typing to configurable enum directive
TheSlimvReal Aug 28, 2023
3e03bbf
adjusted ConfigurableEnumInterface to only allows a fixed set of prop…
TheSlimvReal Aug 28, 2023
d2a68df
refactored locales to be a statically created configurable enum
TheSlimvReal Aug 28, 2023
c6d74cb
fixed tests
TheSlimvReal Aug 28, 2023
90d8748
removed logo as icon property
TheSlimvReal Aug 28, 2023
819e3ba
showing label below picture
TheSlimvReal Aug 28, 2023
81cfb94
Merge branch 'photo-field-label' into configurable_styles
TheSlimvReal Aug 28, 2023
5813fa4
added tests for site settings
TheSlimvReal Aug 28, 2023
fb5fe99
removed unnecessary code
TheSlimvReal Aug 28, 2023
ad6b406
some review changes
TheSlimvReal Aug 28, 2023
c438a78
removed unused prop
TheSlimvReal Sep 5, 2023
feabdff
Merge branch 'master' into configurable_styles
sleidig Sep 6, 2023
ccd015a
Update src/app/core/config/config-fix.ts
sleidig Sep 7, 2023
79fb62b
Update src/app/core/site-settings/demo-site-settings-generator.servic…
sleidig Sep 7, 2023
9e8009a
Update src/app/core/site-settings/site-settings.service.ts
sleidig Sep 7, 2023
4e8fb19
Update src/app/core/site-settings/demo-site-settings-generator.servic…
sleidig Sep 7, 2023
50e9275
Update src/app/core/site-settings/site-settings.ts
sleidig Sep 7, 2023
19c6fa9
cleanup
sleidig Sep 7, 2023
39b2fc6
naming and docs for latest-entity
sleidig Sep 7, 2023
c461b3c
remove test code duplication
sleidig Sep 7, 2023
6341712
use hostname for analytics org rather than the (user-editable) site t…
sleidig Sep 7, 2023
edced57
use background color in import component sticky header
sleidig Sep 7, 2023
f05040f
added code for storing and loading settings
TheSlimvReal Sep 8, 2023
51014fd
Merge remote-tracking branch 'origin/configurable_styles' into config…
TheSlimvReal Sep 8, 2023
d8158a7
fix(core): correctly check permissions for menu items to details pages
sleidig Sep 8, 2023
ffdf141
cache settings in localStorage
sleidig Sep 8, 2023
eae0b78
cleanup
sleidig Sep 8, 2023
70b12bb
Merge branch 'master' into configurable_styles
sleidig Sep 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
498 changes: 201 additions & 297 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@angular/platform-browser-dynamic": "^16.2.1",
"@angular/router": "^16.2.1",
"@angular/service-worker": "^16.2.1",
"@aytek/material-color-picker": "^1.0.4",
"@casl/ability": "^6.5.0",
"@casl/angular": "^8.2.1",
"@faker-js/faker": "^8.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,9 @@
[class.inactive]="!entity.isActive"
class="truncate-text container"
>
<app-fa-dynamic-icon
*ngIf="!imgPath"
[icon]="icon"
class="margin-right-small"
/>
<img *ngIf="imgPath" [src]="imgPath" class="child-pic" alt="" />
<app-display-img [entity]="entity" imgProperty="photo" [defaultIcon]="icon" class="child-pic"></app-display-img>
<span class="font-size-rel">{{ entity?.toString() }}</span>
<span class="subnote" *ngIf="entity?.projectNumber">
({{ entity?.projectNumber }})</span
>
<span class="subnote" *ngIf="entity?.projectNumber"> ({{ entity?.projectNumber }})</span>
</span>

<ng-template #tooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
object-fit: cover;
margin-right: 4px;
vertical-align: middle;
}

.child-pic-large {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
overflow: hidden;
}

.inactive {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,25 @@ import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ChildBlockComponent } from "./child-block.component";
import { ChildrenService } from "../children.service";
import { Child } from "../model/child";
import { FileService } from "app/features/file/file.service";
import { of } from "rxjs";
import { FontAwesomeTestingModule } from "@fortawesome/angular-fontawesome/testing";
import { FileService } from "../../../features/file/file.service";

describe("ChildBlockComponent", () => {
let component: ChildBlockComponent;
let fixture: ComponentFixture<ChildBlockComponent>;
let mockChildrenService: jasmine.SpyObj<ChildrenService>;
let mockFileService: jasmine.SpyObj<FileService>;

beforeEach(waitForAsync(() => {
mockChildrenService = jasmine.createSpyObj("mockChildrenService", [
"getChild",
]);
mockChildrenService.getChild.and.resolveTo(new Child(""));
mockFileService = jasmine.createSpyObj(["loadFile"]);
mockFileService.loadFile.and.returnValue(of("success"));

TestBed.configureTestingModule({
imports: [ChildBlockComponent, FontAwesomeTestingModule],
providers: [
{ provide: ChildrenService, useValue: mockChildrenService },
{ provide: FileService, useValue: mockFileService },
{ provide: FileService, useValue: undefined },
],
}).compileComponents();
}));
Expand All @@ -40,24 +36,4 @@ describe("ChildBlockComponent", () => {
it("should create", () => {
expect(component).toBeTruthy();
});

it("should reset picture if child has none", async () => {
const withPicture = new Child();
withPicture.photo = "some-picture";
component.entity = withPicture;

await component.ngOnChanges({ entity: undefined });

expect(mockFileService.loadFile).toHaveBeenCalled();
expect(component.imgPath).toBeDefined();

mockFileService.loadFile.calls.reset();
// without picture
component.entity = new Child();

await component.ngOnChanges({ entity: undefined });

expect(mockFileService.loadFile).not.toHaveBeenCalled();
expect(component.imgPath).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import { DynamicComponent } from "../../../core/config/dynamic-components/dynami
import { NgIf } from "@angular/common";
import { TemplateTooltipDirective } from "../../../core/common-components/template-tooltip/template-tooltip.directive";
import { ChildBlockTooltipComponent } from "./child-block-tooltip/child-block-tooltip.component";
import { SafeUrl } from "@angular/platform-browser";
import { FileService } from "../../../features/file/file.service";
import { FaDynamicIconComponent } from "../../../core/common-components/fa-dynamic-icon/fa-dynamic-icon.component";
import { DisplayImgComponent } from "../../../features/file/display-img/display-img.component";

@DynamicComponent("ChildBlock")
@Component({
Expand All @@ -24,7 +23,7 @@ import { FaDynamicIconComponent } from "../../../core/common-components/fa-dynam
NgIf,
TemplateTooltipDirective,
ChildBlockTooltipComponent,
FaDynamicIconComponent,
DisplayImgComponent,
],
standalone: true,
})
Expand All @@ -38,7 +37,6 @@ export class ChildBlockComponent implements OnChanges {
/** prevent additional details to be displayed in a tooltip on mouse over */
@Input() tooltipDisabled: boolean;

imgPath: SafeUrl;
icon = Child.icon;

constructor(
Expand All @@ -50,11 +48,5 @@ export class ChildBlockComponent implements OnChanges {
if (changes.hasOwnProperty("entityId")) {
this.entity = await this.childrenService.getChild(this.entityId);
}
this.imgPath = undefined;
if (this.entity?.photo) {
this.fileService
.loadFile(this.entity, "photo")
.subscribe((res) => (this.imgPath = res));
}
}
}
2 changes: 1 addition & 1 deletion src/app/child-dev-project/children/model/child.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class Child extends Entity {

@DatabaseField({
dataType: "file",
label: $localize`:Label for the filename of a photo of a child:Photo Filename`,
label: $localize`:Label for the file field of a photo of a child:Photo`,
editComponent: "EditPhoto",
})
photo: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import { ConfigurableEnumValue } from "../../../core/basic-datatypes/configurabl
* providing special context for {@link Note} categories.
*/
export interface InteractionType extends ConfigurableEnumValue {
/** color highlighting the individual category */
color?: string;
sleidig marked this conversation as resolved.
Show resolved Hide resolved

/** whether the Note is a group type category that stores attendance details for each related person */
isMeeting?: boolean;
}
Expand Down
29 changes: 28 additions & 1 deletion src/app/core/analytics/analytics.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { TestBed } from "@angular/core/testing";

import { AnalyticsService } from "./analytics.service";
import { Angulartics2Matomo, Angulartics2Module } from "angulartics2";
import {
Angulartics2,
Angulartics2Matomo,
Angulartics2Module,
} from "angulartics2";
import { RouterTestingModule } from "@angular/router/testing";
import { ConfigService } from "../config/config.service";
import { UsageAnalyticsConfig } from "./usage-analytics-config";
import { Subject } from "rxjs";
import { Config } from "../config/config";
import { SiteSettingsService } from "../site-settings/site-settings.service";

describe("AnalyticsService", () => {
let service: AnalyticsService;

let mockConfigService: jasmine.SpyObj<ConfigService>;
const configUpdates = new Subject();
let mockMatomo: jasmine.SpyObj<Angulartics2Matomo>;
let mockAngulartics: jasmine.SpyObj<Angulartics2>;
let siteNameSubject = new Subject();

beforeEach(() => {
mockConfigService = jasmine.createSpyObj(
Expand All @@ -25,13 +32,21 @@ describe("AnalyticsService", () => {
"setUsername",
"startTracking",
]);
mockAngulartics = jasmine.createSpyObj([], {
setUserProperties: { next: jasmine.createSpy() },
});

TestBed.configureTestingModule({
imports: [Angulartics2Module.forRoot(), RouterTestingModule],
providers: [
AnalyticsService,
{ provide: ConfigService, useValue: mockConfigService },
{ provide: Angulartics2Matomo, useValue: mockMatomo },
{ provide: Angulartics2, useValue: mockAngulartics },
{
provide: SiteSettingsService,
useValue: { siteName: siteNameSubject },
},
],
});
service = TestBed.inject(AnalyticsService);
Expand Down Expand Up @@ -108,4 +123,16 @@ describe("AnalyticsService", () => {
testAnalyticsConfig2.url + "matomo.php",
]);
});

it("should set the site name as the organisation", () => {
sleidig marked this conversation as resolved.
Show resolved Hide resolved
service.init();
configUpdates.next(new Config());
mockAngulartics.setUserProperties.next["calls"].reset();

siteNameSubject.next("test site name");

expect(mockAngulartics.setUserProperties.next).toHaveBeenCalledWith({
dimension2: "test site name",
});
});
});
9 changes: 3 additions & 6 deletions src/app/core/analytics/analytics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "./usage-analytics-config";
import { Angulartics2, Angulartics2Matomo } from "angulartics2";
import md5 from "md5";
import { UiConfig } from "../ui/ui-config";
import { SiteSettingsService } from "../site-settings/site-settings.service";

/**
* Track usage analytics data and report it to a backend server like Matomo.
Expand All @@ -24,6 +24,7 @@ export class AnalyticsService {
private angulartics2: Angulartics2,
private angulartics2Matomo: Angulartics2Matomo,
private configService: ConfigService,
private siteSettings: SiteSettingsService,
) {}

/**
Expand Down Expand Up @@ -97,11 +98,7 @@ export class AnalyticsService {
if (site_id) {
window["_paq"].push(["setSiteId", site_id]);
}
const { site_name } =
this.configService.getConfig<UiConfig>("appConfig") || {};
if (site_name) {
this.setOrganization(site_name);
}
this.siteSettings.siteName.subscribe((name) => this.setOrganization(name));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with ndb-core. If not, see <http://www.gnu.org/licenses/>.
*/
import {
ConfigurableEnumConfig,
ConfigurableEnumValue,
} from "../configurable-enum.interface";
import { ConfigurableEnumValue } from "../configurable-enum.interface";
import { Entity } from "../../../entity/model/entity";
import { DatabaseField } from "../../../entity/database-field.decorator";
import { EntitySchemaService } from "../../../entity/schema/entity-schema.service";
Expand All @@ -27,9 +24,10 @@ import { ConfigurableEnumService } from "../configurable-enum.service";
import { genders } from "../../../../child-dev-project/children/model/genders";
import { ConfigurableEnumDatatype } from "./configurable-enum.datatype";
import { MockedTestingModule } from "../../../../utils/mocked-testing.module";
import { InteractionType } from "../../../../child-dev-project/notes/model/interaction-type.interface";

describe("Schema data type: configurable-enum", () => {
const TEST_CONFIG: ConfigurableEnumConfig = [
const TEST_CONFIG: InteractionType[] = [
sleidig marked this conversation as resolved.
Show resolved Hide resolved
{ id: "NONE", label: "" },
{ id: "TEST_1", label: "Category 1" },
{ id: "TEST_3", label: "Category 3", color: "#FFFFFF", isMeeting: true },
Expand All @@ -53,7 +51,11 @@ describe("Schema data type: configurable-enum", () => {
let enumService: jasmine.SpyObj<ConfigurableEnumService>;

beforeEach(waitForAsync(() => {
enumService = jasmine.createSpyObj(["getEnumValues", "preLoadEnums"]);
enumService = jasmine.createSpyObj([
"getEnumValues",
"preLoadEnums",
"cacheEnum",
]);
enumService.getEnumValues.and.returnValue(TEST_CONFIG);

TestBed.configureTestingModule({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Directive, Input, TemplateRef, ViewContainerRef } from "@angular/core";
import { ConfigurableEnumService } from "../configurable-enum.service";
import { ConfigurableEnumValue } from "../configurable-enum.interface";

/**
* Enumerate over all {@link ConfigurableEnumConfig} values for the given enum config id.
Expand Down Expand Up @@ -36,4 +37,19 @@ export class ConfigurableEnumDirective {
private viewContainerRef: ViewContainerRef,
private enumService: ConfigurableEnumService,
) {}

/**
* Make sure the template checker knows the type of the context with which the
* template of this directive will be rendered
* See {@link https://angular.io/guide/structural-directives#typing-the-directives-context}
* @param directive
* @param context
*/

static ngTemplateContextGuard(
directive: ConfigurableEnumDirective,
context: unknown,
): context is { $implicit: ConfigurableEnumValue } {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export namespace Ordering {
* of 'greater' or 'less' than is dependent on the concrete enum.
*/
export interface HasOrdinal {
_ordinal: number;
_ordinal?: number;
}

export function hasOrdinalValue(value: any): value is HasOrdinal {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Ordering } from "./configurable-enum-ordering";
import HasOrdinal = Ordering.HasOrdinal;

/**
* Interface specifying overall object representing an enum with all its options
* as stored in the config database
Expand All @@ -10,7 +13,7 @@ export type ConfigurableEnumConfig<
* Mandatory properties of each option of an configurable enum
* the actual object can contain additional properties in the specific context of that enum (e.g. a `color` property)
*/
export interface ConfigurableEnumValue {
export interface ConfigurableEnumValue extends HasOrdinal {
/**
* identifier that is unique among all values of the same enum and does not change even when label or other things are edited
*/
Expand All @@ -33,19 +36,12 @@ export interface ConfigurableEnumValue {
isInvalidOption?: boolean;

/**
* Optionally any number of additional properties specific to a certain enum collection.
* optional styling class that should be applied when displaying this value
*/
[x: string]: any;
style?: string;
}

export const EMPTY: ConfigurableEnumValue = {
id: "",
label: "",
};

/**
* The prefix of all enum collection entries in the config database.
*
* This prefix is concatenated with the individual enum collection's id, resulting in the full config object id.
*/
export const CONFIGURABLE_ENUM_CONFIG_PREFIX = "enum:";
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { EntityAbility } from "../../permissions/ability/entity-ability";

@Injectable({ providedIn: "root" })
export class ConfigurableEnumService {
private enums: Map<string, ConfigurableEnum>;
private enums = new Map<string, ConfigurableEnum>();

constructor(
private entityMapper: EntityMapperService,
Expand All @@ -20,7 +20,6 @@ export class ConfigurableEnumService {

async preLoadEnums() {
const allEnums = await this.entityMapper.loadType(ConfigurableEnum);
this.enums = new Map();
allEnums.forEach((entity) => this.cacheEnum(entity));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ import { DatabaseField } from "../../entity/database-field.decorator";
@DatabaseEntity("ConfigurableEnum")
export class ConfigurableEnum extends Entity {
@DatabaseField() values: ConfigurableEnumValue[] = [];
constructor(id?: string, values: ConfigurableEnumValue[] = []) {
super(id);
this.values = values;
}
}