From e5b9f99b561ecf2b070deffe607a96e07ca5ad47 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Sat, 25 Feb 2023 23:49:59 +0100 Subject: [PATCH] copy operation with modal component added --- src/app/app-routing.module.ts | 2 +- src/app/model/actions.ts | 118 ------------------ src/app/model/actions/action.ts | 21 ++++ src/app/model/actions/actions.ts | 26 ++++ src/app/model/actions/copy-item.ts | 32 +++++ src/app/model/actions/create-folder.ts | 51 ++++++++ src/app/model/actions/delete-item.ts | 40 ++++++ src/app/model/actions/rename-item.ts | 49 ++++++++ src/app/model/ws-item.ts | 2 - .../show-folder/show-folder.component.html | 2 +- src/app/show-folder/show-folder.component.ts | 63 ++++------ src/app/ws-viewer/ws-viewer.component.html | 29 +++++ src/app/ws-viewer/ws-viewer.component.scss | 0 src/app/ws-viewer/ws-viewer.component.spec.ts | 24 ++++ src/app/ws-viewer/ws-viewer.component.ts | 78 ++++++++++++ src/app/ws/ws-routing.module.ts | 1 - src/app/ws/ws.module.ts | 2 +- 17 files changed, 378 insertions(+), 162 deletions(-) delete mode 100644 src/app/model/actions.ts create mode 100644 src/app/model/actions/action.ts create mode 100644 src/app/model/actions/actions.ts create mode 100644 src/app/model/actions/copy-item.ts create mode 100644 src/app/model/actions/create-folder.ts create mode 100644 src/app/model/actions/delete-item.ts create mode 100644 src/app/model/actions/rename-item.ts create mode 100644 src/app/ws-viewer/ws-viewer.component.html create mode 100644 src/app/ws-viewer/ws-viewer.component.scss create mode 100644 src/app/ws-viewer/ws-viewer.component.spec.ts create mode 100644 src/app/ws-viewer/ws-viewer.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 48fc28d..cb5b2dd 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,7 +5,7 @@ const routes: Routes = [ { path: '', loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) - } + }, ]; @NgModule({ imports: [ diff --git a/src/app/model/actions.ts b/src/app/model/actions.ts deleted file mode 100644 index cfef9a7..0000000 --- a/src/app/model/actions.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { AlertOptions } from "@ionic/angular"; -import { title } from "process"; -import { Observable } from "rxjs"; -import { StoragehubService } from "../storagehub.service"; -import { Item } from "./item.model"; -import { WSItem } from "./ws-item"; - -export interface Action { - - getAlertOptions(item: WSItem, storagehub: StoragehubService, postOp?: Function): AlertOptions; - - actionHandler(data: any, storagehub: StoragehubService): Observable; - - getName(): string; - - getActionType(): string | undefined; -} - -export class DeleteAction implements Action { - - getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { - var title = item.getTitle(); - var options: AlertOptions = { - header: `Are you sure to delete item ${title} ?`, - buttons: [{ - text: 'No', - role: 'cancel' - }, - { - text: 'Yes', - handler: () => { - this.actionHandler(item, storagehub).subscribe( - () => reload() - ); - } - }] - }; - return options; - - } - actionHandler(data: WSItem, storagehub: StoragehubService): Observable { - return storagehub.deleteItem(data.item.id); - } - - getName(): string { - return "Delete"; - } - getActionType(): string | undefined { - return "destructive"; - } - -} - -export class RenameAction implements Action { - - getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { - var title = item.getTitle(); - var options: AlertOptions = { - header: 'Rename Item', - message: 'Please specify the new name', - inputs: [ - { - name: 'name', - type: 'text', - placeholder: item.getTitle() - } - ], - buttons: [ - { - text: 'Cancel', - role: 'cancel' - }, - { - text: 'Rename', - handler: (data) => { - this.actionHandler({item: item, newName: data.name}, storagehub).subscribe( - () => reload() - ); - } - } - ] - }; - return options; - - } - actionHandler(data: {item: WSItem, newName : string}, storagehub: StoragehubService): Observable { - return storagehub.renameItem(data.item.item.id, data.newName); - } - - getName(): string { - return "Rename"; - } - getActionType(): string | undefined { - return undefined; - } -} - -export class Actions { - - private static actions: Action[] = [new DeleteAction(), new RenameAction()]; - public static getActionsPerType(type: string): Action[] { - /*switch (type) { - case 'SharedFolder': - break; - case 'FolderItem': - break; - case 'PDFFileItem': - break; - case 'ImageFile': - break; - case 'ExternalLink': - break; - default: - }*/ - return Actions.actions; - } -} - diff --git a/src/app/model/actions/action.ts b/src/app/model/actions/action.ts new file mode 100644 index 0000000..d4eb32c --- /dev/null +++ b/src/app/model/actions/action.ts @@ -0,0 +1,21 @@ +import { AlertOptions, ModalOptions } from "@ionic/angular"; +import { Observable } from "rxjs"; +import { StoragehubService } from "src/app/storagehub.service"; +import { WSItem } from "../ws-item"; + +export abstract class Action { + + getAlertOptions(item: WSItem, storagehub: StoragehubService, postOp?: Function): AlertOptions | undefined{ + return undefined; + } + + getModalOptions(item: WSItem, storagehub: StoragehubService, postOp?: Function): ModalOptions | undefined{ + return undefined; + } + + abstract actionHandler(data: any, storagehub: StoragehubService): Observable; + + abstract getName(): string; + + abstract getActionType(): string | undefined; +} \ No newline at end of file diff --git a/src/app/model/actions/actions.ts b/src/app/model/actions/actions.ts new file mode 100644 index 0000000..57c2d40 --- /dev/null +++ b/src/app/model/actions/actions.ts @@ -0,0 +1,26 @@ +import { Action } from "./action"; +import { CopyAction } from "./copy-item"; +import { DeleteAction } from "./delete-item"; +import { RenameAction } from "./rename-item"; + +export class Actions { + + private static actions: Action[] = [new CopyAction(),new RenameAction(), new DeleteAction()]; + public static getActionsPerType(type: string): Action[] { + /*switch (type) { + case 'SharedFolder': + break; + case 'FolderItem': + break; + case 'PDFFileItem': + break; + case 'ImageFile': + break; + case 'ExternalLink': + break; + default: + }*/ + return Actions.actions; + } +} + diff --git a/src/app/model/actions/copy-item.ts b/src/app/model/actions/copy-item.ts new file mode 100644 index 0000000..ee88419 --- /dev/null +++ b/src/app/model/actions/copy-item.ts @@ -0,0 +1,32 @@ +import { AlertOptions, ModalOptions } from "@ionic/angular"; +import { Observable } from "rxjs"; +import { StoragehubService } from "src/app/storagehub.service"; +import { WsViewerComponent } from "src/app/ws-viewer/ws-viewer.component"; +import { WSItem } from "../ws-item"; +import { Action } from "./action"; + +export class CopyAction extends Action { + + + override getModalOptions(item: WSItem, storagehub: StoragehubService, postOp?: Function): ModalOptions | undefined { + return { + component: WsViewerComponent, + componentProps: { + finishLabel: "Copy here", + title: "Copy "+item.getTitle() + } + }; + } + + + actionHandler(data: {item: WSItem, newName : string}, storagehub: StoragehubService): Observable { + return storagehub.renameItem(data.item.item.id, data.newName); + } + + getName(): string { + return "Copy"; + } + getActionType(): string | undefined { + return undefined; + } +} diff --git a/src/app/model/actions/create-folder.ts b/src/app/model/actions/create-folder.ts new file mode 100644 index 0000000..458cb4d --- /dev/null +++ b/src/app/model/actions/create-folder.ts @@ -0,0 +1,51 @@ +import { AlertOptions, ModalOptions } from "@ionic/angular"; +import { Observable } from "rxjs"; +import { StoragehubService } from "src/app/storagehub.service"; +import { WSItem } from "../ws-item"; +import { Action } from "./action"; + +export class CreateFolderAction extends Action { + + override getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { + var title = item.getTitle(); + var options: AlertOptions = { + header: 'Create folder', + message: 'Please specify the name of the new folder', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'new folder' + } + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel' + }, + { + text: 'Create', + handler: (data) => { + this.actionHandler({wsitem: item, name: data.name}, storagehub).subscribe( + () => reload() + ); + + } + } + ] + }; + return options; + + } + actionHandler(data: {wsitem: WSItem, name : string}, storagehub: StoragehubService): Observable { + return storagehub.createFolder(data.wsitem.item.id, data.name, ""); + } + + getName(): string { + return "Create Folder"; + } + getActionType(): string | undefined { + return undefined; + } + +} diff --git a/src/app/model/actions/delete-item.ts b/src/app/model/actions/delete-item.ts new file mode 100644 index 0000000..da8a4f8 --- /dev/null +++ b/src/app/model/actions/delete-item.ts @@ -0,0 +1,40 @@ +import { AlertOptions } from "@ionic/angular"; +import { Observable } from "rxjs"; +import { StoragehubService } from "src/app/storagehub.service"; +import { WSItem } from "../ws-item"; +import { Action } from "./action"; + +export class DeleteAction extends Action { + + override getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { + var title = item.getTitle(); + var options: AlertOptions = { + header: `Are you sure to delete item ${title} ?`, + buttons: [{ + text: 'No', + role: 'cancel' + }, + { + text: 'Yes', + handler: () => { + this.actionHandler(item, storagehub).subscribe( + () => reload() + ); + } + }] + }; + return options; + + } + actionHandler(data: WSItem, storagehub: StoragehubService): Observable { + return storagehub.deleteItem(data.item.id); + } + + getName(): string { + return "Delete"; + } + getActionType(): string | undefined { + return "destructive"; + } + +} \ No newline at end of file diff --git a/src/app/model/actions/rename-item.ts b/src/app/model/actions/rename-item.ts new file mode 100644 index 0000000..2037e47 --- /dev/null +++ b/src/app/model/actions/rename-item.ts @@ -0,0 +1,49 @@ +import { AlertOptions } from "@ionic/angular"; +import { Observable } from "rxjs"; +import { StoragehubService } from "src/app/storagehub.service"; +import { WSItem } from "../ws-item"; +import { Action } from "./action"; + +export class RenameAction extends Action { + + override getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { + var title = item.getTitle(); + var options: AlertOptions = { + header: 'Rename Item', + message: 'Please specify the new name', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: item.getTitle() + } + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel' + }, + { + text: 'Rename', + handler: (data) => { + this.actionHandler({item: item, newName: data.name}, storagehub).subscribe( + () => reload() + ); + } + } + ] + }; + return options; + + } + actionHandler(data: {item: WSItem, newName : string}, storagehub: StoragehubService): Observable { + return storagehub.renameItem(data.item.item.id, data.newName); + } + + getName(): string { + return "Rename"; + } + getActionType(): string | undefined { + return undefined; + } +} diff --git a/src/app/model/ws-item.ts b/src/app/model/ws-item.ts index cde109d..0ef454b 100644 --- a/src/app/model/ws-item.ts +++ b/src/app/model/ws-item.ts @@ -1,5 +1,3 @@ -import { StoragehubService } from "../storagehub.service"; -import { Action, Actions } from "./actions"; import { Item } from "./item.model"; export class WSItem { diff --git a/src/app/show-folder/show-folder.component.html b/src/app/show-folder/show-folder.component.html index 72b4236..ee3ea62 100644 --- a/src/app/show-folder/show-folder.component.html +++ b/src/app/show-folder/show-folder.component.html @@ -28,7 +28,7 @@ - + diff --git a/src/app/show-folder/show-folder.component.ts b/src/app/show-folder/show-folder.component.ts index fcbb3ab..4e3f4af 100644 --- a/src/app/show-folder/show-folder.component.ts +++ b/src/app/show-folder/show-folder.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, Input, CUSTOM_ELEMENTS_SCHEMA, Output, EventEmitter, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/core'; -import { Platform, AlertController, ToastController, IonicModule, ActionSheetController, ActionSheetButton, AlertOptions } from '@ionic/angular'; +import { Platform, AlertController, ToastController, IonicModule, ActionSheetController, ActionSheetButton, AlertOptions, ModalController, ModalOptions } from '@ionic/angular'; import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; import { Router, ActivatedRoute } from '@angular/router'; @@ -10,7 +10,10 @@ import { CommonModule } from '@angular/common'; import { Item } from '../model/item.model'; import { MatIconModule } from '@angular/material/icon'; import { WSItem } from '../model/ws-item'; -import { Action, Actions } from '../model/actions'; +import { Action } from '../model/actions/action'; +import { CreateFolderAction } from '../model/actions/create-folder'; +import { Actions } from '../model/actions/actions'; +import { WsViewerComponent } from '../ws-viewer/ws-viewer.component'; @Component({ standalone: true, @@ -41,7 +44,7 @@ export class ShowFolderComponent implements OnInit { private actionSheetCtrl: ActionSheetController, private storagehub: StoragehubService, private alertCtrl: AlertController, - private ref: ChangeDetectorRef + private modalCtrl: ModalController ) { } ngOnInit(): void { @@ -53,7 +56,7 @@ export class ShowFolderComponent implements OnInit { console.log("loadDoc called"); this.storagehub.getChildren(this.parentItem.item.id).subscribe( (res) => { - const tmpItems$ : WSItem[] = [] + const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.items = tmpItems$; }) @@ -84,34 +87,9 @@ export class ShowFolderComponent implements OnInit { } async createFolder() { - this.presentAlertControl({ - header: 'Create folder', - message: 'Please specify the name of the new folder', - inputs: [ - { - name: 'name', - type: 'text', - placeholder: 'new folder' - } - ], - buttons: [ - { - text: 'Cancel', - role: 'cancel' - }, - { - text: 'Create', - handler: (data) => { - if (this.parentItem) { - const createFolder$ = this.storagehub.createFolder(this.parentItem.item.id, data.name, ""); - createFolder$.subscribe( - suc => this.loadDocuments() - ); - } - } - } - ] - }); + var createFolderAction: CreateFolderAction = new CreateFolderAction(); + if (this.parentItem) + this.actionHandler(createFolderAction, this.parentItem); } async presentActionSheet(item: WSItem) { @@ -151,13 +129,22 @@ export class ShowFolderComponent implements OnInit { await alert.present(); } - async actionHandler(action: Action, item: WSItem) { - var options: AlertOptions = action.getAlertOptions(item, this.storagehub, () => { this.loadDocuments() }); - if (options) { - await this.presentAlertControl(options); - } else - action.actionHandler(item, this.storagehub); + async presentModal(options: ModalOptions) { + let modal = await this.modalCtrl.create(options); + await modal.present(); + } + async actionHandler(action: Action, item: WSItem) { + var alertOptions: undefined | AlertOptions = action.getAlertOptions(item, this.storagehub, () => { this.loadDocuments() }); + if (alertOptions) { + await this.presentAlertControl(alertOptions); + } else { + var modalOptions: undefined | ModalOptions = action.getModalOptions(item, this.storagehub, () => { this.loadDocuments() }); + if (modalOptions) + await this.presentModal(modalOptions); + else + action.actionHandler(item, this.storagehub); + } } } diff --git a/src/app/ws-viewer/ws-viewer.component.html b/src/app/ws-viewer/ws-viewer.component.html new file mode 100644 index 0000000..6f0ff34 --- /dev/null +++ b/src/app/ws-viewer/ws-viewer.component.html @@ -0,0 +1,29 @@ + + + + Cancel + + {{ title }} + + + + +

Empty folder

+
+ + + {{ i.getIconInfo() }} + + {{ i.getTitle() }} + + keyboard_arrow_right + + +
+ + + + {{ finishLabel }} + + + \ No newline at end of file diff --git a/src/app/ws-viewer/ws-viewer.component.scss b/src/app/ws-viewer/ws-viewer.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/ws-viewer/ws-viewer.component.spec.ts b/src/app/ws-viewer/ws-viewer.component.spec.ts new file mode 100644 index 0000000..ab40dcd --- /dev/null +++ b/src/app/ws-viewer/ws-viewer.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { WsViewerComponent } from './ws-viewer.component'; + +describe('WsViewerComponent', () => { + let component: WsViewerComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ WsViewerComponent ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(WsViewerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/ws-viewer/ws-viewer.component.ts b/src/app/ws-viewer/ws-viewer.component.ts new file mode 100644 index 0000000..3d8d98d --- /dev/null +++ b/src/app/ws-viewer/ws-viewer.component.ts @@ -0,0 +1,78 @@ +import { CommonModule } from '@angular/common'; +import { Component, Input, OnInit } from '@angular/core'; +import { MatIconModule } from '@angular/material/icon'; +import { IonicModule, ModalController } from '@ionic/angular'; +import { WSItem } from '../model/ws-item'; +import { StoragehubService } from '../storagehub.service'; + +@Component({ + standalone: true, + selector: 'app-ws-viewer', + providers: [StoragehubService], + templateUrl: './ws-viewer.component.html', + styleUrls: ['./ws-viewer.component.scss'], + imports: [ + CommonModule, IonicModule, MatIconModule + ] +}) +export class WsViewerComponent implements OnInit { + + constructor(private storagehub: StoragehubService, private modalCtrl: ModalController) { } + + @Input() toExcludeOnOperation: string[] = []; + @Input() finishLabel: string = "Confirm"; + @Input() title: string = "Operation"; + + currentItem: WSItem | undefined; + + items: WSItem[] = [] + + ngOnInit() { + this.loadDocuments(); + } + + loadDocuments() { + if (this.currentItem) { + this.storagehub.getChildren(this.currentItem.item.id).subscribe( + (res) => { + const tmpItems$: WSItem[] = [] + res.forEach(i => tmpItems$.push(new WSItem(i))); + this.items = tmpItems$.sort(this.sort); + }) + } else + this.storagehub.getWsRoot().subscribe( + (res) => this.addVresToWs(new WSItem(res)) + ); + + } + + addVresToWs(wsRoot: WSItem) { + this.storagehub.getVres().subscribe( + (res) => { + const tmpItems$: WSItem[] = [wsRoot] + res.forEach(i => tmpItems$.push(new WSItem(i))); + this.items = tmpItems$; + }) + } + + itemClicked(item: WSItem) { + this.currentItem = item; + this.ngOnInit(); + } + + cancel() { + return this.modalCtrl.dismiss(null, 'cancel'); + } + + confirm() { + return this.modalCtrl.dismiss(null, 'confirm'); + } + + sort(item1: WSItem, item2: WSItem) { + if (item1.isFolder() && !item2.isFolder()) return -1; + if (!item1.isFolder() && item2.isFolder()) return 1; + if (item1.item.title > item2.item.title) return -1; + if (item1.item.title < item2.item.title) return 1; + return 0; + } +} diff --git a/src/app/ws/ws-routing.module.ts b/src/app/ws/ws-routing.module.ts index 1b77f7a..9baa29a 100644 --- a/src/app/ws/ws-routing.module.ts +++ b/src/app/ws/ws-routing.module.ts @@ -1,6 +1,5 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { ShowFolderComponent } from '../show-folder/show-folder.component'; import { WsPage } from './ws.page'; const routes: Routes = [ diff --git a/src/app/ws/ws.module.ts b/src/app/ws/ws.module.ts index 9d4ac78..3961dda 100644 --- a/src/app/ws/ws.module.ts +++ b/src/app/ws/ws.module.ts @@ -15,7 +15,7 @@ import { ShowFolderComponent } from '../show-folder/show-folder.component'; FormsModule, ExploreContainerComponentModule, WsPageRoutingModule, - ShowFolderComponent + ShowFolderComponent, ], declarations: [WsPage] })