Skip to content

Commit

Permalink
fix(Admin UI): improvements & bug fixes for setup wizard (#2375)
Browse files Browse the repository at this point in the history
closes #2370
  • Loading branch information
sleidig authored May 8, 2024
1 parent 288db3a commit 30b0463
Show file tree
Hide file tree
Showing 29 changed files with 1,186 additions and 745 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<div class="hint-banner" i18n>
You can edit how users will see the details of a single record of this type.
Drag and drop fields and sections in this preview of a profile view and group
them as appropriate. The editor below closely resembles how the form will look
for users later.
<br />
We recommend to keep things simple: Only add fields that you really need for
your work.
</div>

<app-view-title [disableBackButton]="true" [displayInPlace]="true">
&lt;Name of displayed {{ this.entityConstructor?.label }}&gt;
</app-view-title>
<p i18n>
You can edit how users will see the details of a single record of this type.
Drag and drop fields and sections in this preview of a profile view and group
them as appropriate. We recommend to keep things simple: Only add fields that
you really need for your work.
</p>

<app-admin-tabs [tabs]="config?.panels" [newTabFactory]="newPanelFactory">
<ng-template [appAdminTabTemplate]="config?.panels" let-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import { AdminTabTemplateDirective } from "../../building-blocks/admin-tabs/admi
@Component({
selector: "app-admin-entity-details",
templateUrl: "./admin-entity-details.component.html",
styleUrls: ["./admin-entity-details.component.scss"],
styleUrls: [
"./admin-entity-details.component.scss",
"../../admin-entity/admin-entity-styles.scss",
],
standalone: true,
imports: [
MatTabsModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { MatInputModule } from "@angular/material/input";
import {
FormBuilder,
Expand Down Expand Up @@ -26,7 +26,7 @@ import { HelpButtonComponent } from "../../../../common-components/help-button/h
templateUrl: "./configure-entity-field-validator.component.html",
styleUrl: "./configure-entity-field-validator.component.scss",
})
export class ConfigureEntityFieldValidatorComponent {
export class ConfigureEntityFieldValidatorComponent implements OnInit {
validatorForm: FormGroup;
@Input() entitySchemaField: EntitySchemaField;
@Output() entityValidatorChanges = new EventEmitter<DynamicValidator>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
<div class="hint-banner" i18n>
You can edit how users will see the list of all records of this type. Drag and
drop filters and change table columns in this preview. The editor below
closely resembles how the list will look for users later.
<br />
To create new fields, use the "Details View" section.
</div>

<app-view-title [disableBackButton]="true" [displayInPlace]="true">
{{ entityConstructor.labelPlural }}
</app-view-title>
Expand Down Expand Up @@ -40,15 +48,14 @@
</div>

<div class="table-content-preview" i18n>
Drag & drop filters and add filters using the
Add Filter:
<app-entity-fields-menu
[entityType]="entityConstructor"
[activeFields]="filters"
(activeFieldsChange)="updateFilters($event)"
[availableFields]="allFields"
icon="square-plus"
></app-entity-fields-menu>
button
</div>
</div>

Expand Down Expand Up @@ -85,14 +92,13 @@
</div>

<div class="table-content-preview" i18n>
Drag & drop table column headers and add columns using the
Drag & drop table column headers. Add columns:
<app-entity-fields-menu
[entityType]="entityConstructor"
[(activeFields)]="item.columns"
[availableFields]="allFields"
icon="square-plus"
></app-entity-fields-menu>
button
</div>
</ng-template>
</app-admin-tabs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ import { ViewTitleComponent } from "../../common-components/view-title/view-titl
CdkDropListGroup,
],
templateUrl: "./admin-entity-list.component.html",
styleUrl: "./admin-entity-list.component.scss",
styleUrls: [
"./admin-entity-list.component.scss",
"../admin-entity/admin-entity-styles.scss",
],
})
export class AdminEntityListComponent implements OnChanges, AfterViewInit {
@ViewChild(CdkDropList) placeholder: CdkDropList;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<h2 i18n>General Settings of "{{ entityConstructor.label }}" Records</h2>
<p i18n>
<div class="hint-banner" i18n>
The settings here apply to the entity type overall and take effect everywhere
the entity is displayed, including lists, forms and other views.
</p>
</div>

<h2 i18n>General Settings of "{{ entityConstructor.label }}" Records</h2>

<form [formGroup]="basicSettingsForm">
<mat-tab-group>
Expand All @@ -17,6 +18,7 @@ <h2 i18n>General Settings of "{{ entityConstructor.label }}" Records</h2>
<mat-form-field floatLabel="always">
<mat-label>
<span i18n>Label (Plural)</span>
&nbsp;
<fa-icon
icon="question-circle"
matTooltip="Optionally you can define how multiple records of this entity should be called, e.g. in lists."
Expand All @@ -33,24 +35,31 @@ <h2 i18n>General Settings of "{{ entityConstructor.label }}" Records</h2>
<mat-form-field floatLabel="always">
<mat-label>
<span i18n>Icon</span>
&nbsp;
<fa-icon
icon="question-circle"
matTooltip="The icon to represent this entity type, e.g. when displaying records as a small preview block. [see fontawesome.com/icons]"
matTooltip="The icon to represent this entity type, e.g. when displaying records as a small preview block."
i18n-matTooltip
></fa-icon>
</mat-label>
<input
formControlName="icon"
matInput
[placeholder]="formLabel.value"
/>
<input formControlName="icon" matInput />

<mat-hint i18n>
Find available icon names at
<a
href="https://fontawesome.com/v6/search?o=r&m=free"
target="_blank"
>fontawesome.com</a
>
</mat-hint>
</mat-form-field>
</div>

<div class="entity-form-cell">
<mat-form-field>
<mat-label>
<span i18n>Generated Title of Record</span>
&nbsp;
<fa-icon
icon="question-circle"
matTooltip="Select the fields that should be used (in that order) to generate a simple name/title for a record. This generated title is used in previews, search and for form fields that allow to select a record of this type. (Only text fields can be used here)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ import { FaIconComponent } from "@fortawesome/angular-fontawesome";
selector: "app-admin-entity-general-settings",
standalone: true,
templateUrl: "./admin-entity-general-settings.component.html",
styleUrl: "./admin-entity-general-settings.component.scss",
styleUrls: [
"./admin-entity-general-settings.component.scss",
"../admin-entity-styles.scss",
],
imports: [
MatButtonModule,
MatInputModule,
Expand Down Expand Up @@ -86,11 +89,8 @@ export class AdminEntityGeneralSettingsComponent implements OnInit {
this.basicSettingsForm = this.fb.group({
label: [this.generalSettings.label, Validators.required],
labelPlural: [this.generalSettings.labelPlural],
icon: [this.generalSettings.icon, Validators.required],
toStringAttributes: [
this.generalSettings.toStringAttributes,
Validators.required,
],
icon: [this.generalSettings.icon],
toStringAttributes: [this.generalSettings.toStringAttributes],
hasPII: [this.generalSettings.hasPII],
});
this.showPIIDetails = this.basicSettingsForm.get("hasPII").value;
Expand Down
9 changes: 9 additions & 0 deletions src/app/core/admin/admin-entity/admin-entity-styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@use "@angular/material/core/style/elevation" as
mat-elevation;

.hint-banner {
background: #e8e8e8;
padding: 1em;
margin-bottom: 1em;
@include mat-elevation.elevation(1);
}
2 changes: 2 additions & 0 deletions src/app/core/admin/admin-entity/admin-entity.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
>
General Settings
</mat-list-item>

<app-beta-feature></app-beta-feature>
</mat-nav-list>

<div class="config-component flex-grow mat-elevation-z1">
Expand Down
4 changes: 3 additions & 1 deletion src/app/core/admin/admin-entity/admin-entity.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { ActivatedRoute, RouterLink } from "@angular/router";
import { MatListItem, MatNavList } from "@angular/material/list";
import { AdminEntityDetailsComponent } from "../admin-entity-details/admin-entity-details/admin-entity-details.component";
import { AdminEntityGeneralSettingsComponent } from "./admin-entity-general-settings/admin-entity-general-settings.component";
import { BetaFeatureComponent } from "../../../features/coming-soon/beta-feature/beta-feature.component";

@Component({
selector: "app-admin-entity",
Expand All @@ -52,6 +53,7 @@ import { AdminEntityGeneralSettingsComponent } from "./admin-entity-general-sett
MatListItem,
AdminEntityDetailsComponent,
AdminEntityGeneralSettingsComponent,
BetaFeatureComponent,
],
templateUrl: "./admin-entity.component.html",
styleUrl: "./admin-entity.component.scss",
Expand Down Expand Up @@ -80,7 +82,7 @@ export class AdminEntityComponent implements OnInit {
ngOnInit(): void {
this.init();
this.routes.queryParams.subscribe((params) => {
this.mode = params.mode;
this.mode = params.mode ?? this.mode;
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@if (showSetupWizard) {
<button
mat-flat-button
routerLink="/admin/setup-wizard"
(click)="navigateToWizard()"
class="button"
color="accent"
style="border-radius: 0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper
import { mockEntityMapper } from "../../../entity/entity-mapper/mock-entity-mapper-service";
import { SetupWizardConfig } from "../setup-wizard-config";
import { Config } from "../../../config/config";
import { Router } from "@angular/router";

describe("SetupWizardButtonComponent", () => {
let component: SetupWizardButtonComponent;
Expand Down Expand Up @@ -41,10 +42,37 @@ describe("SetupWizardButtonComponent", () => {
new Config("", testWizardConfig),
);

// @ts-ignore
component.init();
component.ngOnInit();
tick();

expect(component.showSetupWizard).toBeFalse();
}));

it("should auto navigate to setup wizard if configured openOnStart", fakeAsync(() => {
const routerSpy = spyOn(TestBed.inject(Router), "navigate");
const testWizardConfig: SetupWizardConfig = { steps: [] };
spyOn(TestBed.inject(EntityMapperService), "load").and.resolveTo(
new Config("", testWizardConfig),
);

// don't re-route if disabled in config
testWizardConfig.openOnStart = false;
component.ngOnInit();
tick();
expect(routerSpy).not.toHaveBeenCalled();

// don't re-route if finished
testWizardConfig.finished = true;
testWizardConfig.openOnStart = true;
component.ngOnInit();
tick();
expect(routerSpy).not.toHaveBeenCalled();

// re-route automatically if configured
testWizardConfig.openOnStart = true;
testWizardConfig.finished = false;
component.ngOnInit();
tick();
expect(routerSpy).toHaveBeenCalled();
}));
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import { FaIconComponent } from "@fortawesome/angular-fontawesome";
import { MatButton } from "@angular/material/button";
import { RouterLink } from "@angular/router";
import { Router } from "@angular/router";
import { EntityMapperService } from "../../../entity/entity-mapper/entity-mapper.service";
import { Config } from "../../../config/config";
import {
Expand All @@ -16,25 +16,27 @@ import { LoggingService } from "../../../logging/logging.service";
@Component({
selector: "app-setup-wizard-button",
standalone: true,
imports: [FaIconComponent, MatButton, RouterLink],
imports: [FaIconComponent, MatButton],
templateUrl: "./setup-wizard-button.component.html",
styleUrls: ["./setup-wizard-button.component.scss"],
})
export class SetupWizardButtonComponent {
export class SetupWizardButtonComponent implements OnInit {
showSetupWizard: boolean;

constructor(
private entityMapper: EntityMapperService,
private logger: LoggingService,
) {
this.init();
}
private router: Router,
) {}

private init() {
ngOnInit() {
this.entityMapper
.load(Config, CONFIG_SETUP_WIZARD_ID)
.then((r: Config<SetupWizardConfig>) => {
this.updateStatus(r.data);
if (!r.data.finished && r.data.openOnStart) {
this.navigateToWizard();
}
})
.catch((e) => this.logger.debug("No Setup Wizard Config found"));

Expand All @@ -50,4 +52,8 @@ export class SetupWizardButtonComponent {
private updateStatus(config: SetupWizardConfig) {
this.showSetupWizard = !config.finished;
}

navigateToWizard() {
this.router.navigate(["/admin/setup-wizard"]);
}
}
10 changes: 4 additions & 6 deletions src/app/core/admin/setup-wizard/setup-wizard-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,23 @@ import { MenuItem } from "../../ui/navigation/menu-item";
export const CONFIG_SETUP_WIZARD_ID = "Config:SetupWizard";

export interface SetupWizardConfig {
/** index of the current (last visited) step, to be opened when user returns to the wizard **/
currentStep?: number;

/** whether the wizard has been completed overall and should be hidden */
finished?: boolean;

/** whether users should on startup be navigated automatically to the setup wizard screen while it is not finished */
openOnStart?: boolean;

steps: SetupWizardStep[];
}

export interface SetupWizardStep {
title: string;
text: string;
actions?: MenuItem[];

/** whether the user(s) have completed this step yet */
completed?: boolean;
}

export const defaultSetupWizardConfig: SetupWizardConfig = {
openOnStart: false,
steps: [
{
title: $localize`:Setup Wizard Step Title:Welcome`,
Expand Down
Loading

0 comments on commit 30b0463

Please sign in to comment.