diff --git a/frontend/projects/marketplace/src/pipes/filter-packages.pipe.ts b/frontend/projects/marketplace/src/pipes/filter-packages.pipe.ts index 2dbfaa7e6..3626b1e29 100644 --- a/frontend/projects/marketplace/src/pipes/filter-packages.pipe.ts +++ b/frontend/projects/marketplace/src/pipes/filter-packages.pipe.ts @@ -88,7 +88,10 @@ export class FilterPackagesPipe implements PipeTransform { return packages .filter(p => category === 'all' || p.categories.includes(category)) .sort((a, b) => { - return a['published-at'] > b['published-at'] ? -1 : 1 + return ( + new Date(b['published-at']).valueOf() - + new Date(a['published-at']).valueOf() + ) }) } } diff --git a/frontend/projects/ui/src/app/app/preloader/preloader.component.html b/frontend/projects/ui/src/app/app/preloader/preloader.component.html index 88408d6a0..d262af0fd 100644 --- a/frontend/projects/ui/src/app/app/preloader/preloader.component.html +++ b/frontend/projects/ui/src/app/app/preloader/preloader.component.html @@ -41,7 +41,6 @@ - diff --git a/frontend/projects/ui/src/app/app/preloader/preloader.component.ts b/frontend/projects/ui/src/app/app/preloader/preloader.component.ts index 60919b738..42767903f 100644 --- a/frontend/projects/ui/src/app/app/preloader/preloader.component.ts +++ b/frontend/projects/ui/src/app/app/preloader/preloader.component.ts @@ -71,7 +71,6 @@ const ICONS = [ 'remove', 'remove-circle-outline', 'remove-outline', - 'reorder-three', 'rocket-outline', 'save-outline', 'shield-checkmark-outline', diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.html b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.html deleted file mode 100644 index ea18e6613..000000000 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - {{ rec.title }} - {{ rec.version | displayEmver }} - - - - - - - - - - - - - - - diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.ts deleted file mode 100644 index f7c2a397c..000000000 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-rec/app-list-rec.component.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Inject, - Input, - Output, -} from '@angular/core' -import { AlertController } from '@ionic/angular' -import { ErrorToastService } from '@start9labs/shared' -import { AbstractMarketplaceService } from '@start9labs/marketplace' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { from, merge, OperatorFunction, pipe, Subject } from 'rxjs' -import { catchError, map, startWith, switchMap, tap } from 'rxjs/operators' -import { RecoveredInfo } from 'src/app/util/parse-data-model' -import { MarketplaceService } from 'src/app/services/marketplace.service' - -@Component({ - selector: 'app-list-rec', - templateUrl: 'app-list-rec.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppListRecComponent { - // Asynchronous actions initiators - readonly install$ = new Subject() - readonly delete$ = new Subject() - - @Input() - rec!: RecoveredInfo - - @Output() - readonly deleted = new EventEmitter() - - // Installing package - readonly installing$ = this.install$.pipe( - switchMap(({ id, version }) => - // Mapping each installation to API request - this.marketplaceService - .installPackage({ - id, - 'version-spec': `>=${version}`, - 'version-priority': 'min', - }) - .pipe( - // Mapping operation to true/false loading indication - loading(this.errToast), - ), - ), - ) - - // Deleting package - readonly deleting$ = this.delete$.pipe( - switchMap(({ id }) => - // Mapping each deletion to API request - from(this.api.deleteRecoveredPackage({ id })).pipe( - // Notifying parent component that package is removed from recovered items - tap(() => this.deleted.emit()), - // Mapping operation to true/false loading indication - loading(this.errToast), - ), - ), - ) - - // Merging both true/false loading indicators to a single stream - readonly loading$ = merge(this.installing$, this.deleting$) - - constructor( - private readonly api: ApiService, - private readonly errToast: ErrorToastService, - private readonly alertCtrl: AlertController, - @Inject(AbstractMarketplaceService) - private readonly marketplaceService: MarketplaceService, - ) {} - - async deleteRecovered(pkg: RecoveredInfo): Promise { - const alert = await this.alertCtrl.create({ - header: 'Delete Data', - message: `This action will permanently delete all data associated with ${pkg.title}.`, - buttons: [ - { - text: 'Cancel', - role: 'cancel', - }, - { - text: 'Delete', - handler: () => { - // Initiate deleting of 'pkg' - this.delete$.next(pkg) - }, - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } -} - -// Custom RxJS operator to turn asynchronous operation into a true/false loading indicator -function loading( - errToast: ErrorToastService, -): OperatorFunction { - return pipe( - // Show notification on error - catchError(e => from(errToast.present(e))), - // Map any result to false to stop loading indicator - map(() => false), - // Start operation with true - startWith(true), - ) -} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.html b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.html deleted file mode 100644 index 9de70de83..000000000 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.html +++ /dev/null @@ -1,63 +0,0 @@ - - - {{ reordering ? 'Reorder' : 'Installed Services' }} - 1" - slot="end" - fill="clear" - (click)="toggle()" - strong - > - - {{ reordering ? 'Done' : 'Reorder' }} - - - - - - - - - - - - - - {{ pkg.entry.manifest.title }} - {{ pkg.entry.manifest.version | displayEmver }} - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.scss b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.scss deleted file mode 100644 index 9ade72b01..000000000 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} \ No newline at end of file diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts deleted file mode 100644 index cc2c1c0ec..000000000 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - Output, -} from '@angular/core' -import { ItemReorderEventDetail } from '@ionic/core' -import { PackageDataEntry } from 'src/app/services/patch-db/data-model' - -@Component({ - selector: 'app-list-reorder', - templateUrl: 'app-list-reorder.component.html', - styleUrls: ['app-list-reorder.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppListReorderComponent { - @Input() - reordering = false - - @Input() - pkgs: readonly PackageDataEntry[] = [] - - @Output() - readonly reorderingChange = new EventEmitter() - - @Output() - readonly pkgsChange = new EventEmitter() - - toggle() { - this.reordering = !this.reordering - this.reorderingChange.emit(this.reordering) - } - - reorder({ detail }: CustomEvent): void { - this.pkgs = detail.complete([...this.pkgs]) - this.pkgsChange.emit(this.pkgs) - } -} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts index 97cc80ea8..4c76afe6a 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts @@ -14,8 +14,6 @@ import { UiPipeModule } from 'src/app/pipes/ui/ui.module' import { AppListIconComponent } from './app-list-icon/app-list-icon.component' import { AppListEmptyComponent } from './app-list-empty/app-list-empty.component' import { AppListPkgComponent } from './app-list-pkg/app-list-pkg.component' -import { AppListRecComponent } from './app-list-rec/app-list-rec.component' -import { AppListReorderComponent } from './app-list-reorder/app-list-reorder.component' import { PackageInfoPipe } from './package-info.pipe' const routes: Routes = [ @@ -42,8 +40,6 @@ const routes: Routes = [ AppListIconComponent, AppListEmptyComponent, AppListPkgComponent, - AppListRecComponent, - AppListReorderComponent, PackageInfoPipe, ], }) diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.html b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.html index 24d3e52dd..b6e7b9550 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.html +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.html @@ -21,23 +21,20 @@ > - + Installed Services - - - Recovered Services - - - + + + + + + + diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.scss b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.scss index 8a42dee41..e69de29bb 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.scss +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.scss @@ -1,3 +0,0 @@ -ion-item-divider { - margin-bottom: 16px; -} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts index 3a717e15d..1776c80e0 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts @@ -4,11 +4,9 @@ import { DataModel, PackageDataEntry, } from 'src/app/services/patch-db/data-model' -import { Observable } from 'rxjs' -import { filter, map, switchMap, take, takeUntil, tap } from 'rxjs/operators' -import { isEmptyObject, exists, DestroyService } from '@start9labs/shared' +import { filter, takeUntil, tap } from 'rxjs/operators' +import { DestroyService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model' @Component({ selector: 'app-list', @@ -19,8 +17,6 @@ import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model' export class AppListPage { loading = true pkgs: readonly PackageDataEntry[] = [] - recoveredPkgs: readonly RecoveredInfo[] = [] - reordering = false constructor( private readonly api: ApiService, @@ -29,62 +25,22 @@ export class AppListPage { ) {} get empty(): boolean { - return !this.pkgs.length && isEmptyObject(this.recoveredPkgs) + return !this.pkgs.length } ngOnInit() { this.patch - .watch$() + .watch$('package-data') .pipe( - filter(data => exists(data) && !isEmptyObject(data)), - take(1), - map(parseDataModel), - tap(({ pkgs, recoveredPkgs }) => { + filter(pkgs => Object.keys(pkgs).length !== this.pkgs.length), + tap(pkgs => { this.loading = false - this.pkgs = pkgs - this.recoveredPkgs = recoveredPkgs + this.pkgs = Object.values(pkgs).sort((a, b) => + b.manifest.title > a.manifest.title ? -1 : 1, + ) }), - switchMap(() => this.watchNewlyRecovered()), takeUntil(this.destroy$), ) .subscribe() } - - onReordering(reordering: boolean): void { - if (!reordering) { - this.setOrder() - } - - this.reordering = reordering - } - - deleteRecovered(rec: RecoveredInfo): void { - this.recoveredPkgs = this.recoveredPkgs.filter(item => item !== rec) - } - - private watchNewlyRecovered(): Observable { - return this.patch.watch$('package-data').pipe( - filter(pkgs => !!pkgs && Object.keys(pkgs).length !== this.pkgs.length), - tap(pkgs => { - const ids = Object.keys(pkgs) - const newIds = ids.filter( - id => !this.pkgs.find(pkg => pkg.manifest.id === id), - ) - - // remove uninstalled - const filtered = this.pkgs.filter(pkg => ids.includes(pkg.manifest.id)) - - // add new entry to beginning of array - const added = newIds.map(id => pkgs[id]) - - this.pkgs = [...added, ...filtered] - this.recoveredPkgs = this.recoveredPkgs.filter(rec => !pkgs[rec.id]) - }), - ) - } - - private setOrder(): void { - const order = this.pkgs.map(pkg => pkg.manifest.id) - this.api.setDbValue({ pointer: '/pkg-order', value: order }) - } } diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts index 606fdf56d..4fd995a31 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -10,8 +10,7 @@ import { ActivatedRoute } from '@angular/router' import { PatchDB } from 'patch-db-client' import { ServerNameService } from 'src/app/services/server-name.service' import { Observable, of } from 'rxjs' -import { take, tap } from 'rxjs/operators' -import { isEmptyObject, ErrorToastService } from '@start9labs/shared' +import { ErrorToastService } from '@start9labs/shared' import { EOSService } from 'src/app/services/eos.service' import { LocalStorageService } from 'src/app/services/local-storage.service' import { OSUpdatePage } from 'src/app/modals/os-update/os-update.page' @@ -25,7 +24,6 @@ import { DataModel } from 'src/app/services/patch-db/data-model' styleUrls: ['server-show.page.scss'], }) export class ServerShowPage { - hasRecoveredPackage = false clicks = 0 readonly server$ = this.patch.watch$('server-info') @@ -48,34 +46,14 @@ export class ServerShowPage { private readonly authService: AuthService, ) {} - ngOnInit() { - this.patch - .watch$('recovered-packages') - .pipe( - take(1), - tap(data => (this.hasRecoveredPackage = !isEmptyObject(data))), - ) - .subscribe() - } - async updateEos(): Promise { - if (this.hasRecoveredPackage) { - const alert = await this.alertCtrl.create({ - header: 'Cannot Update', - message: - 'You cannot update EmbassyOS when you have unresolved recovered services.', - buttons: ['OK'], - }) - await alert.present() - } else { - const modal = await this.modalCtrl.create({ - componentProps: { - releaseNotes: this.eosService.eos?.['release-notes'], - }, - component: OSUpdatePage, - }) - modal.present() - } + const modal = await this.modalCtrl.create({ + componentProps: { + releaseNotes: this.eosService.eos?.['release-notes'], + }, + component: OSUpdatePage, + }) + modal.present() } async presentAlertLogout() { diff --git a/frontend/projects/ui/src/app/services/api/api.fixures.ts b/frontend/projects/ui/src/app/services/api/api.fixures.ts index f964da7ac..88cca7471 100644 --- a/frontend/projects/ui/src/app/services/api/api.fixures.ts +++ b/frontend/projects/ui/src/app/services/api/api.fixures.ts @@ -748,7 +748,7 @@ export module Mock { icon: PROXY_ICON, }, }, - 'published-at': new Date().toISOString(), + 'published-at': new Date(new Date().valueOf() + 10).toISOString(), }, }, 'btc-rpc-proxy': { diff --git a/frontend/projects/ui/src/app/services/api/api.types.ts b/frontend/projects/ui/src/app/services/api/api.types.ts index e3bf51a4e..e4264fbd7 100644 --- a/frontend/projects/ui/src/app/services/api/api.types.ts +++ b/frontend/projects/ui/src/app/services/api/api.types.ts @@ -223,9 +223,6 @@ export module RR { export type UninstallPackageReq = { id: string } // package.uninstall export type UninstallPackageRes = null - export type DeleteRecoveredPackageReq = { id: string } // package.delete-recovered - export type DeleteRecoveredPackageRes = null - export type DryConfigureDependencyReq = { 'dependency-id': string 'dependent-id': string diff --git a/frontend/projects/ui/src/app/services/api/embassy-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-api.service.ts index 28b818647..14fa77bc5 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-api.service.ts @@ -216,10 +216,6 @@ export abstract class ApiService { params: RR.DryConfigureDependencyReq, ): Promise - abstract deleteRecoveredPackage( - params: RR.UninstallPackageReq, - ): Promise - abstract sideloadPackage( params: RR.SideloadPackageReq, ): Promise diff --git a/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts index e1c121794..e9544e134 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -364,12 +364,6 @@ export class LiveApiService extends ApiService { return this.rpcRequest({ method: 'package.stop', params }) } - async deleteRecoveredPackage( - params: RR.DeleteRecoveredPackageReq, - ): Promise { - return this.rpcRequest({ method: 'package.delete-recovered', params }) - } - async uninstallPackage( params: RR.UninstallPackageReq, ): Promise { diff --git a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 80e778d36..3fa2fa348 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -814,19 +814,6 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async deleteRecoveredPackage( - params: RR.DeleteRecoveredPackageReq, - ): Promise { - await pauseFor(2000) - const patch: RemoveOperation[] = [ - { - op: PatchOp.REMOVE, - path: `/recovered-packages/${params.id}`, - }, - ] - return this.withRevision(patch) - } - async dryConfigureDependency( params: RR.DryConfigureDependencyReq, ): Promise { @@ -892,10 +879,6 @@ export class MockApiService extends ApiService { op: PatchOp.REMOVE, path: `/package-data/${id}/install-progress`, }, - { - op: PatchOp.REMOVE, - path: `/recovered-packages/${id}`, - }, ] this.mockRevision(patch2) }, 1000) diff --git a/frontend/projects/ui/src/app/services/api/mock-patch.ts b/frontend/projects/ui/src/app/services/api/mock-patch.ts index 3af7daf0b..75037d8fb 100644 --- a/frontend/projects/ui/src/app/services/api/mock-patch.ts +++ b/frontend/projects/ui/src/app/services/api/mock-patch.ts @@ -44,13 +44,6 @@ export const mockPatchData: DataModel = { }, hostname: 'random-words', }, - 'recovered-packages': { - 'btc-rpc-proxy': { - title: 'Bitcoin Proxy', - icon: 'assets/img/service-icons/btc-rpc-proxy.png', - version: '0.2.2', - }, - }, 'package-data': { bitcoind: { state: PackageState.Installed, diff --git a/frontend/projects/ui/src/app/services/patch-db/data-model.ts b/frontend/projects/ui/src/app/services/patch-db/data-model.ts index f1a8e797e..b4ca5f463 100644 --- a/frontend/projects/ui/src/app/services/patch-db/data-model.ts +++ b/frontend/projects/ui/src/app/services/patch-db/data-model.ts @@ -6,7 +6,6 @@ import { BasicInfo } from 'src/app/pages/developer-routes/developer-menu/form-in export interface DataModel { 'server-info': ServerInfo 'package-data': { [id: string]: PackageDataEntry } - 'recovered-packages': { [id: string]: RecoveredPackageDataEntry } ui: UIData } @@ -75,11 +74,6 @@ export enum ServerStatus { Updated = 'updated', BackingUp = 'backing-up', } -export interface RecoveredPackageDataEntry { - title: string - icon: Url - version: string -} export interface PackageDataEntry { state: PackageState diff --git a/frontend/projects/ui/src/app/util/parse-data-model.ts b/frontend/projects/ui/src/app/util/parse-data-model.ts deleted file mode 100644 index d24fd9803..000000000 --- a/frontend/projects/ui/src/app/util/parse-data-model.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - DataModel, - PackageDataEntry, - RecoveredPackageDataEntry, -} from 'src/app/services/patch-db/data-model' - -export function parseDataModel(data: DataModel): ParsedData { - const all: Record = JSON.parse( - JSON.stringify(data['package-data']), - ) - - // recovered packages (0.2.x) - const recoveredPkgs = Object.entries(data['recovered-packages']) - .filter(([id, _]) => !all[id]) - .map(([id, val]) => ({ - ...val, - id, - })) - - // installed packages - const order = [...(data.ui['pkg-order'] || [])] - const pkgs: PackageDataEntry[] = [] - // add known packages in preferential order - order.forEach(id => { - if (all[id]) { - pkgs.push(all[id]) - - delete all[id] - } - }) - - // unshift unknown packages - Object.values(all).forEach(pkg => { - pkgs.unshift(pkg) - }) - - return { - pkgs, - recoveredPkgs, - } -} - -export interface RecoveredInfo extends RecoveredPackageDataEntry { - id: string -} - -interface ParsedData { - pkgs: PackageDataEntry[] - recoveredPkgs: RecoveredInfo[] -}
{{ rec.version | displayEmver }}
{{ pkg.entry.manifest.version | displayEmver }}