Skip to content

Commit

Permalink
NAS-131283 / 25.04 / Provide single entry point for installing a cust…
Browse files Browse the repository at this point in the history
…om app (#10758)

* NAS-131283: Provide single entry point for installing a custom app

* NAS-131283: Provide single entry point for installing a custom app
  • Loading branch information
denysbutenko authored Sep 30, 2024
1 parent 1b88656 commit 43477fb
Show file tree
Hide file tree
Showing 99 changed files with 266 additions and 26 deletions.
5 changes: 2 additions & 3 deletions src/app/constants/catalog.constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const officialCatalog = 'TRUENAS';
export const customApp = 'ix-chart';
export const customAppTrain = 'charts';
export const customApp = 'ix-app';
export const customAppTrain = 'stable';
export const appImagePlaceholder = 'assets/images/truenas_scale_ondark_favicon.png';
export const latestVersion = 'latest';
6 changes: 0 additions & 6 deletions src/app/pages/apps/apps-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { marker as T } from '@biesbjerg/ngx-translate-extract-marker';
import { customApp, customAppTrain } from 'app/constants/catalog.constants';
import { AppWizardComponent } from 'app/pages/apps/components/app-wizard/app-wizard.component';
import { AppsScopeWrapperComponent } from 'app/pages/apps/components/apps-scope-wrapper.component';
import { AvailableAppsComponent } from 'app/pages/apps/components/available-apps/available-apps.component';
import { CategoryViewComponent } from 'app/pages/apps/components/available-apps/category-view/category-view.component';
import { CustomAppFormComponent } from 'app/pages/apps/components/custom-app-form/custom-app-form.component';
import { DockerImagesListComponent } from 'app/pages/apps/components/docker-images/docker-images-list/docker-images-list.component';
import { ContainerLogsComponent } from 'app/pages/apps/components/installed-apps/container-logs/container-logs.component';
import { ContainerShellComponent } from 'app/pages/apps/components/installed-apps/container-shell/container-shell.component';
Expand Down Expand Up @@ -88,10 +86,6 @@ const routes: Routes = [
path: ':category',
component: CategoryViewComponent,
},
{
path: `${customAppTrain}/${customApp}/install`,
component: CustomAppFormComponent,
},
{
path: ':train/:appId',
component: AppRouterOutletComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h3>{{ 'Application Info' | translate }}</h3>
<ngx-skeleton-loader></ngx-skeleton-loader>
} @else {
<div>
@for (source of app().sources; track source; let last = $last) {
@for (source of app()?.sources; track source; let last = $last) {
<a
class="source-link"
target="_blank"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ <h2>{{ 'Screenshots' | translate }}</h2>
<ix-app-json-details-card
class="app-info-card"
[title]="'Run As Context' | translate"
[jsonDetails]="app().run_as_context"
[jsonDetails]="app()?.run_as_context"
[isLoading]="isLoading()"
></ix-app-json-details-card>

<ix-app-json-details-card
class="app-info-card"
[title]="'Capabilities' | translate"
[jsonDetails]="app().capabilities"
[jsonDetails]="app()?.capabilities"
[isLoading]="isLoading()"
></ix-app-json-details-card>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class AppWizardComponent implements OnInit, OnDestroy {
pageTitle$ = this._pageTitle$.asObservable().pipe(
filter(Boolean),
map((name) => {
if (name === customApp) {
if (name?.toLocaleLowerCase() === customApp?.toLocaleLowerCase()) {
return `${this.titlePrefix} ${this.translate.instant('Custom App')}`;
}
return `${this.titlePrefix} ${name}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
<div
class="custom-app-wrapper"
[matTooltip]="'Setup Pool To Create Custom App' | translate"
[matTooltipDisabled]="!(customAppDisabled$ | async)"
>
<a
<button
*ixRequiresRoles="requiredRoles"
mat-button
color="primary"
ixTest="custom-app"
[disabled]="customAppDisabled$ | async"
[ixUiSearch]="searchableElements.elements.customApp"
(click)="navigateToCustomAppCreation()"
(click)="openAppWizardCreation()"
>{{ 'Custom App' | translate }}</button>

<button
mat-icon-button
ixTest="custom-app-menu"
[matMenuTriggerFor]="customAppMenu"
>
{{ 'Custom App' | translate }}
</a>
<ix-icon name="more_vert"></ix-icon>
</button>
<mat-menu #customAppMenu="matMenu">
<button
*ixRequiresRoles="requiredRoles"
mat-menu-item
ixTest="custom-app-yaml"
[disabled]="customAppDisabled$ | async"
[ixUiSearch]="searchableElements.elements.customAppYaml"
(click)="openCustomAppYamlCreation()"
>{{ 'Install via YAML' | translate}}</button>
</mat-menu>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.custom-app-wrapper {
align-items: center;
display: flex;
gap: 8px;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatMenuHarness } from '@angular/material/menu/testing';
import { Router } from '@angular/router';
import { SpectatorRouting } from '@ngneat/spectator';
import { createRoutingFactory, mockProvider } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';
import { of } from 'rxjs';
import { of, Subject } from 'rxjs';
import { customAppTrain, customApp } from 'app/constants/catalog.constants';
import { mockAuth } from 'app/core/testing/utils/mock-auth.utils';
import { AppCardComponent } from 'app/pages/apps/components/available-apps/app-card/app-card.component';
import { CustomAppButtonComponent } from 'app/pages/apps/components/available-apps/custom-app-button/custom-app-button.component';
import { CustomAppFormComponent } from 'app/pages/apps/components/custom-app-form/custom-app-form.component';
import { DockerStore } from 'app/pages/apps/store/docker.store';
import { IxSlideInService } from 'app/services/ix-slide-in.service';

// TODO: https://ixsystems.atlassian.net/browse/NAS-129579
describe.skip('CustomAppButtonComponent', () => {
describe('CustomAppButtonComponent', () => {
let spectator: SpectatorRouting<CustomAppButtonComponent>;
let loader: HarnessLoader;
let button: MatButtonHarness;
Expand All @@ -27,6 +29,12 @@ describe.skip('CustomAppButtonComponent', () => {
mockProvider(DockerStore, {
selectedPool$: of('selected pool'),
}),
mockProvider(IxSlideInService, {
onClose$: new Subject<unknown>(),
open: jest.fn(() => {
return { slideInClosed$: of(true) };
}),
}),
],
});

Expand Down Expand Up @@ -58,4 +66,14 @@ describe.skip('CustomAppButtonComponent', () => {

expect(button.isDisabled()).toBeTruthy();
});

it('checks menu and CustomAppForm to install via YAML', async () => {
const menu = await loader.getHarness(MatMenuHarness);
await menu.open();

const installButton = await menu.getItems({ text: /Install via YAML$/ });
await installButton[0].click();

expect(spectator.inject(IxSlideInService).open).toHaveBeenCalledWith(CustomAppFormComponent, { wide: true });
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Router } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { map, tap } from 'rxjs';
import { filter, map } from 'rxjs';
import { customAppTrain, customApp } from 'app/constants/catalog.constants';
import { Role } from 'app/enums/role.enum';
import { customAppButtonElements } from 'app/pages/apps/components/available-apps/custom-app-button/custom-app-button.elements';
import { CustomAppFormComponent } from 'app/pages/apps/components/custom-app-form/custom-app-form.component';
Expand All @@ -26,17 +27,21 @@ export class CustomAppButtonComponent {
constructor(
private dockerStore: DockerStore,
private router: Router,
private ixSlideIn: IxSlideInService,
private slideIn: IxSlideInService,
) { }

navigateToCustomAppCreation(): void {
const ref = this.ixSlideIn.open(CustomAppFormComponent, { wide: true });
openAppWizardCreation(): void {
this.router.navigate(['/apps', 'available', customAppTrain, customApp, 'install']);
}

openCustomAppYamlCreation(): void {
const ref = this.slideIn.open(CustomAppFormComponent, { wide: true });
ref.slideInClosed$.pipe(
tap(Boolean),
filter(Boolean),
untilDestroyed(this),
).subscribe({
next: () => {
this.router.navigate(['/', 'apps']);
this.router.navigate(['/apps']);
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export const customAppButtonElements = {
hierarchy: [T('Custom App')],
anchor: 'custom-app',
},
customAppYaml: {
hierarchy: [T('Custom App via YAML')],
anchor: 'custom-app-yaml',
},
},
visibleTokens: [GlobalSearchVisibleToken.Apps],
} satisfies UiSearchableElement;
2 changes: 2 additions & 0 deletions src/assets/i18n/af.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/az.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/br.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -2228,6 +2229,7 @@
"Install Application": "",
"Install Manual Update File": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installation Media": "",
"Installed": "",
"Installed Apps": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@
"Custom ({customTransfers})": "",
"Custom ACME Server Directory URI": "",
"Custom App": "",
"Custom App via YAML": "",
"Custom Config": "",
"Custom Name": "",
"Custom Transfers": "",
Expand Down Expand Up @@ -1724,6 +1725,7 @@
"Install Another Instance": "",
"Install Application": "",
"Install NDIVIA Drivers": "",
"Install via YAML": "",
"Installed": "",
"Installed Apps": "",
"Installer image file": "",
Expand Down
Loading

0 comments on commit 43477fb

Please sign in to comment.