Skip to content

Commit

Permalink
create features-missing dialog for edit-UI
Browse files Browse the repository at this point in the history
  • Loading branch information
iJungleboy committed Sep 27, 2024
1 parent 20f1c50 commit a89bdf0
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
<mat-card>
<mat-card-header>
<mat-card-title>{{ feature.name }}</mat-card-title>
<mat-card-title>{{ feature().name }}</mat-card-title>
</mat-card-header>
<mat-card-content>
<p [innerHtml]="feature.description | safeHtml"></p>
<p [innerHtml]="feature().description | safeHtml"></p>
<!-- Name ID -->
<div class="eav-info-row">
<div class="eav-info-row__label">ID:</div>
<div class="eav-info-row__value">
<span (click)="copyToClipboard(feature.nameId)">{{ feature.nameId }}</span>
<span (click)="copyToClipboard(feature().nameId)">{{ feature().nameId }}</span>
</div>
</div>
<!-- Status -->
@if (mySpecs().showStatus) {
<div class="eav-info-row">
<div class="eav-info-row__label">{{ "Features.Status" | translate }}:</div>
<div class="eav-info-row__value">
<span>{{ (feature().isEnabled ? "Features.Active" : "Features.NotActive") | translate }}</span>
</div>
</div>
}
<!-- GUID -->
<div class="eav-info-row">
<div class="eav-info-row__label">GUID:</div>
<div class="eav-info-row__value eav_click">
<span (click)="copyToClipboard(feature.guid)">{{ feature.guid }}</span>
@if (mySpecs().showGuid) {
<div class="eav-info-row">
<div class="eav-info-row__label">GUID:</div>
<div class="eav-info-row__value eav_click">
<span (click)="copyToClipboard(feature().guid)">{{ feature().guid }}</span>
</div>
</div>
</div>
}
<!-- Security Rating -->
<div class="eav-info-row">
<div class="eav-info-row__label">Security Rating:</div>
<div class="eav-info-row__value">
<span>{{ feature.security.Impact + ': ' + feature.security.Message }}</span>
<span>{{ feature().security.Impact + ': ' + feature().security.Message }}</span>
</div>
</div>
</mat-card-content>
<mat-card-actions align="end">
<a [href]="feature.link" target="_blank" mat-raised-button class="eav-card-action-button" color="accent">
<a [href]="feature().link" target="_blank" mat-raised-button class="eav-card-action-button" color="accent">
<mat-icon>open_in_new</mat-icon>
Find out more
</a>
<button mat-raised-button class="eav-card-action-button" (click)="dialog.close()">
Close
</button>
@if (mySpecs().showClose != false) {
<button mat-raised-button class="eav-card-action-button" (click)="dialog.close()">
Close
</button>
}
</mat-card-actions>
</mat-card>
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, input, Optional } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TranslateModule } from '@ngx-translate/core';
import { TippyDirective } from '../../../shared/directives/tippy.directive';
import { copyToClipboard } from '../../../shared/helpers/copy-to-clipboard.helper';
import { SafeHtmlPipe } from '../../../shared/pipes/safe-html.pipe';
import { computedObj } from '../../../shared/signals/signal.utilities';
import { FeatureDetailsDialogData } from './feature-details-dialog.models';

@Component({
Expand All @@ -19,17 +21,23 @@ import { FeatureDetailsDialogData } from './feature-details-dialog.models';
MatIconModule,
TippyDirective,
SafeHtmlPipe,
TranslateModule,
]
})
export class FeatureDetailsDialogComponent {

specs = input<FeatureDetailsDialogData>();

constructor(
@Inject(MAT_DIALOG_DATA) public dialogData: FeatureDetailsDialogData,
@Optional() @Inject(MAT_DIALOG_DATA) private dialogSpecs: FeatureDetailsDialogData,
protected dialog: MatDialogRef<FeatureDetailsDialogComponent>,
private snackBar: MatSnackBar,
) { }

protected feature = this.dialogData.feature;
protected mySpecs = computedObj('mySpecs', () => this.dialogSpecs ?? this.specs());

protected feature = computedObj('feature', () => this.mySpecs().feature);


// TODO: @2pp - this code is duplicated in ca. 6 places
// Please create a simple ClipboardService for this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ import { Feature } from '../../../features/models/feature.model';

export interface FeatureDetailsDialogData {
feature: Feature;
showGuid: boolean;
showStatus: boolean;
showClose?: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
import { AgGridAngular } from '@ag-grid-community/angular';
import { GridOptions } from '@ag-grid-community/core';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { GridOptions, ModuleRegistry } from '@ag-grid-community/core';
import { AsyncPipe, NgClass } from '@angular/common';
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialog, MatDialogActions } from '@angular/material/dialog';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { RouterOutlet } from '@angular/router';
import { BehaviorSubject, catchError, forkJoin, map, Observable, of, share, startWith, Subject, switchMap, tap, timer } from 'rxjs';
import { transient } from '../../core';
import { ExpirationExtension } from '../../features/expiration-extension';
import { FeatureState } from '../../features/models';
import { Feature } from '../../features/models/feature.model';
import { ColumnDefinitions } from '../../shared/ag-grid/column-definitions';
import { BooleanFilterComponent } from '../../shared/components/boolean-filter/boolean-filter.component';
import { IdFieldComponent } from '../../shared/components/id-field/id-field.component';
import { IdFieldParams } from '../../shared/components/id-field/id-field.models';
import { defaultGridOptions } from '../../shared/constants/default-grid-options.constants';
import { Feature } from '../../features/models/feature.model';
import { TippyDirective } from '../../shared/directives/tippy.directive';
import { SxcGridModule } from '../../shared/modules/sxc-grid-module/sxc-grid.module';
import { DialogRoutingService } from '../../shared/routing/dialog-routing.service';
import { License } from '../models/license.model';
import { FeaturesConfigService } from '../services/features-config.service';
import { ActiveFeaturesCountPipe } from './active-features-count.pipe';
import { AgGridHeightDirective } from './ag-grid-height.directive';
import { FeatureDetailsDialogComponent } from './feature-details-dialog/feature-details-dialog.component';
import { FeatureDetailsDialogData } from './feature-details-dialog/feature-details-dialog.models';
import { FeaturesListEnabledReasonComponent } from './features-list-enabled-reason/features-list-enabled-reason.component';
import { FeaturesListEnabledComponent } from './features-list-enabled/features-list-enabled.component';
import { FeaturesStatusComponent } from './features-status/features-status.component';
import { FeaturesStatusParams } from './features-status/features-status.models';
import { ExpirationExtension } from '../../features/expiration-extension';
import { ActiveFeaturesCountPipe } from './active-features-count.pipe';
import { LicensesOrderPipe } from './licenses-order.pipe';
import { MatButtonModule } from '@angular/material/button';
import { AgGridHeightDirective } from './ag-grid-height.directive';
import { NgClass, AsyncPipe } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { TippyDirective } from '../../shared/directives/tippy.directive';
import { FeaturesConfigService } from '../services/features-config.service';
import { ModuleRegistry } from '@ag-grid-community/core';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColumnDefinitions } from '../../shared/ag-grid/column-definitions';
import { SxcGridModule } from '../../shared/modules/sxc-grid-module/sxc-grid.module';
import { transient } from '../../core';
import { DialogRoutingService } from '../../shared/routing/dialog-routing.service';

@Component({
selector: 'app-license-info',
Expand Down Expand Up @@ -127,6 +126,8 @@ export class LicenseInfoComponent implements OnInit, OnDestroy {
#showFeatureDetails(feature: Feature): void {
const data: FeatureDetailsDialogData = {
feature,
showGuid: true,
showStatus: true,
};
this.dialog.open(FeatureDetailsDialogComponent, {
autoFocus: false,
Expand Down
4 changes: 3 additions & 1 deletion projects/eav-ui/src/app/edit/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,7 @@
},
"Features": {
"NotActivated": "Diese Funktion ist nicht aktiviert - mehr erfahren"
}
},
"License-EditUi-Warning-Label": "Lizenz ⚠️",
"License-EditUi-Warning-Tooltip": "Du verwendest Funktionen, die nicht lizenziert sind."
}
4 changes: 3 additions & 1 deletion projects/eav-ui/src/app/edit/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,5 +290,7 @@
"FindOutMore": "Find out more",
"Tooltip": "Feature: {{Name}} ({{NameId}})",
"Close": "Close"
}
},
"License-EditUi-Warning-Label": "License ⚠️",
"License-EditUi-Warning-Tooltip": "You're using features which are not licensed."
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<mat-card class="eav-header">
<button mat-icon-button class="eav-exit-button" (click)="close()"
[tippy]="(formConfig.config.isParentDialog ? 'Form.Buttons.Exit.Tip' : 'Form.Buttons.Return.Tip') | translate">
<mat-icon class="eav-icon">{{ formConfig.config.isParentDialog ? 'clear' : 'arrow_back' }}</mat-icon>
<button mat-icon-button class="eav-exit-button" (click)="close()" [tippyTranslate]="'Form.Buttons.' + (config.isParentDialog ? 'Exit' : 'Return') + '.Tip'">
<mat-icon class="eav-icon">{{ config.isParentDialog ? 'clear' : 'arrow_back' }}</mat-icon>
</button>
<div class="eav-languages">
@if (hasLanguages) {
Expand All @@ -15,16 +14,21 @@
lock
</mat-icon>
}
@if (formConfig.config.isCopy) {
@if (config.isCopy) {
<mat-icon class="eav-hint-icon" tippyTranslate="General.CopyHint">
file_copy
</mat-icon>
}
<button mat-button class="eav-publish-button" [disabled]="readOnly().isReadOnly" (click)="openPublishStatusDialog()"
[tippyTranslate]="'PublishStatus.' + publishMode() + '.Tip' | translate">
[tippyTranslate]="'PublishStatus.' + publishMode() + '.Tip'">
<span class="eav-publish-mode">
{{ 'PublishStatus.Label' | translate }}
<b>{{ 'PublishStatus.' + publishMode() | translate | uppercase }}</b>
</span>
</button>
@if (showLicenseWarning()) {
<button mat-button tippyTranslate="License-EditUi-Warning-Tooltip" (click)="openUnlicensedDialog()">
{{ 'License-EditUi-Warning-Label' | translate }} ⚠️
</button>
}
</mat-card>
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AsyncPipe, UpperCasePipe } from '@angular/common';
import { UpperCasePipe } from '@angular/common';
import { Component, computed, EventEmitter, inject, Input, Output, ViewContainerRef } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDialog } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { FeaturesScopedService } from '../../../features/features-scoped.service';
import { openFeaturesUsedButUnlicensedDialog } from '../../../features/features-used-but-missing-dialog/features-used-but-unlicensed-dialog.component';
import { TippyDirective } from '../../../shared/directives/tippy.directive';
import { FormConfigService } from '../../form/form-config.service';
import { FormPublishingService } from '../../form/form-publishing.service';
Expand All @@ -23,7 +25,6 @@ import { PublishStatusDialogComponent } from './publish-status-dialog/publish-st
MatButtonModule,
MatIconModule,
LanguageSwitcherComponent,
AsyncPipe,
UpperCasePipe,
TranslateModule,
TippyDirective,
Expand All @@ -33,15 +34,8 @@ export class EditDialogHeaderComponent {
@Input() disabled: boolean;
@Output() private closeDialog = new EventEmitter<null>();

private formsStateService = inject(FormsStateService);
protected readOnly = this.formsStateService.readOnly;

protected publishMode = this.publishStatusService.getPublishMode(this.formConfig.config.formId)

protected hasLanguages = computed(() => {
const languages = this.languageService.getAllSignal();
return languages().length > 0
});
#formsStateSvc = inject(FormsStateService);
#features = inject(FeaturesScopedService);

constructor(
private dialog: MatDialog,
Expand All @@ -51,6 +45,17 @@ export class EditDialogHeaderComponent {
public formConfig: FormConfigService,
) { }

protected config = this.formConfig.config;
protected readOnly = this.#formsStateSvc.readOnly;
protected publishMode = this.publishStatusService.getPublishMode(this.formConfig.config.formId)

protected hasLanguages = computed(() => {
const languages = this.languageService.getAllSignal();
return languages().length > 0
});

protected showLicenseWarning = this.#features.hasUnlicensedFeatures;

close() {
this.closeDialog.emit();
}
Expand All @@ -62,4 +67,9 @@ export class EditDialogHeaderComponent {
width: '350px',
});
}

openUnlicensedDialog() {
openFeaturesUsedButUnlicensedDialog(this.dialog, this.viewContainerRef);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface EavEditLoadDto extends EavPublishStatus {
Items: EavEntityBundleDto[];
Prefetch?: Prefetch;
Settings: EditSettingsDto;

RequiredFeatures?: Record<string, string[]>;
}

export interface EditSettings {
Expand Down
38 changes: 19 additions & 19 deletions projects/eav-ui/src/app/edit/form/edit-initializer.service.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
import { ContentTypeItemService } from '../shared/content-types/content-type-item.service';
import { Injectable, signal } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { transient } from '../../core';
import { FeaturesScopedService } from '../../features/features-scoped.service';
import { InputTypeHelpers } from '../../shared/fields/input-type-helpers';
import { UpdateEnvVarsFromDialogSettings } from '../../shared/helpers/update-env-vars-from-dialog-settings.helper';
import { convertUrlToForm } from '../../shared/helpers/url-prep.helper';
import { FeaturesScopedService } from '../../features/features-scoped.service';
import { classLog } from '../../shared/logging';
import { ItemAddIdentifier } from '../../shared/models/edit-form.model';
import { calculateIsParentDialog, sortLanguages } from '../dialog/main/edit-dialog-main.helpers';
import { EavEditLoadDto } from '../dialog/main/edit-dialog-main.models';
import { EditUrlParams } from '../routing/edit-url-params.model';
import { EntityReader } from '../shared/helpers';
import { EavEntity } from '../shared/models/eav/eav-entity';
import { ItemAddIdentifier } from '../../shared/models/edit-form.model';
import { FieldLogicManager } from '../fields/logic/field-logic-manager';
import { EavContentType } from '../shared/models/eav/eav-content-type';
import { FormDataService } from './form-data.service';
import { InputTypeHelpers } from '../../shared/fields/input-type-helpers';
import { FieldReader } from '../localization/field-reader';
import { FormConfigService } from './form-config.service';
import { ItemValuesOfLanguage } from '../state/item-values-of-language.model';
import { transient } from '../../core';
import { LanguageService } from '../localization/language.service';
import { EditUrlParams } from '../routing/edit-url-params.model';
import { AdamCacheService } from '../shared/adam/adam-cache.service';
import { LinkCacheService } from '../shared/adam/link-cache.service';
import { ContentTypeItemService } from '../shared/content-types/content-type-item.service';
import { ContentTypeService } from '../shared/content-types/content-type.service';
import { ItemService } from '../state/item.service';
import { EntityReader } from '../shared/helpers';
import { InputTypeService } from '../shared/input-types/input-type.service';
import { FormPublishingService } from './form-publishing.service';
import { LanguageService } from '../localization/language.service';
import { FormLanguageService } from './form-language.service';
import { LinkCacheService } from '../shared/adam/link-cache.service';
import { EavContentType } from '../shared/models/eav/eav-content-type';
import { EavEntity } from '../shared/models/eav/eav-entity';
import { FieldsSettingsHelpers } from '../state/field-settings.helper';
import { classLog } from '../../shared/logging';
import { ItemValuesOfLanguage } from '../state/item-values-of-language.model';
import { ItemService } from '../state/item.service';
import { FormConfigService } from './form-config.service';
import { FormDataService } from './form-data.service';
import { FormLanguageService } from './form-language.service';
import { FormPublishingService } from './form-publishing.service';

const logSpecs = {
all: false,
Expand Down Expand Up @@ -115,7 +115,7 @@ export class EditInitializerService {


// SDV: document what's happening here
this.featuresService.load(formData.Context);
this.featuresService.load(formData.Context, formData);
UpdateEnvVarsFromDialogSettings(formData.Context.App);
this.#importLoadedData(formData);
this.#keepInitialValues();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Component } from '@angular/core';
import { FeatureComponentBase } from '../shared/base-feature.component';
import { TranslateModule } from '@ngx-translate/core';
import { AsyncPipe } from '@angular/common';
import { Component } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { TippyDirective } from '../../shared/directives/tippy.directive';
import { FeatureComponentBase } from '../shared/base-feature.component';

@Component({
selector: 'app-feature-icon',
templateUrl: './feature-icon.component.html',
styleUrls: ['./feature-icon.component.scss'],
standalone: true,
imports: [
MatIconModule,
Expand Down
Loading

0 comments on commit a89bdf0

Please sign in to comment.