Skip to content

Create file viewer v2 #582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: PER-10107-implement-unlisted-share-page-ui
Choose a base branch
from
Open
72 changes: 72 additions & 0 deletions src/app/core/resolves/record-resolve-v2.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Injectable } from '@angular/core';
import {
ActivatedRoute,
ActivatedRouteSnapshot,
RouterStateSnapshot,
} from '@angular/router';
import * as _ from 'lodash';

import { ApiService } from '@shared/services/api/api.service';
import { DataService } from '@shared/services/data/data.service';
import { MessageService } from '@shared/services/message/message.service';

import { RecordResponse } from '@shared/services/api/index.repo';
import { RecordVO } from '@root/app/models';
import { DataStatus } from '@models/data-status.enum';

@Injectable()
export class RecordResolveV2Service {
constructor(
private api: ApiService,
private dataService: DataService,
private message: MessageService,
private route: ActivatedRoute,

Check warning on line 23 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L20-L23

Added lines #L20 - L23 were not covered by tests
) {}

async resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Promise<RecordVO> {
const localItem = this.dataService.getItemByArchiveNbr(

Check warning on line 30 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L30

Added line #L30 was not covered by tests
route.params.recArchiveNbr,
);

const itemId = route.params.recordId;

Check warning on line 34 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L34

Added line #L34 was not covered by tests

const token = route.params.token;

Check warning on line 36 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L36

Added line #L36 was not covered by tests

const headers = {

Check warning on line 38 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L38

Added line #L38 was not covered by tests
'X-Permanent-Share-Token': token,
};

try {

Check warning on line 42 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L42

Added line #L42 was not covered by tests
if (localItem && localItem.dataStatus === DataStatus.Full) {
return Promise.resolve(localItem as RecordVO);

Check warning on line 44 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L44

Added line #L44 was not covered by tests
} else if (localItem) {
await this.dataService.fetchFullItems([localItem]);
return localItem as RecordVO;

Check warning on line 47 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L46-L47

Added lines #L46 - L47 were not covered by tests
} else {
const response = await this.api.record.get(

Check warning on line 49 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L49

Added line #L49 was not covered by tests
[
new RecordVO({
recordId: itemId,
}),
],
true,
headers,
);

const record: any = response[0];

Check warning on line 59 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L59

Added line #L59 was not covered by tests
if (record) {
record.dataStatus = DataStatus.Full;

Check warning on line 61 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L61

Added line #L61 was not covered by tests
}
return record;

Check warning on line 63 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L63

Added line #L63 was not covered by tests
}
} catch (err) {
if (err instanceof RecordResponse) {
this.message.showError({ message: err.getMessage(), translate: true });

Check warning on line 67 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L67

Added line #L67 was not covered by tests
}
throw err;

Check warning on line 69 in src/app/core/resolves/record-resolve-v2.service.ts

View check run for this annotation

Codecov / codecov/patch

src/app/core/resolves/record-resolve-v2.service.ts#L69

Added line #L69 was not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ export class FileListControlsComponent implements OnDestroy, HasSubscriptions {

setAvailableActions() {
this.isShareRoot =
this.data.currentFolder.type === 'type.folder.root.share';
this.isPublic = this.data.currentFolder.type.includes('public');
this.data.currentFolder?.type === 'type.folder.root.share';
this.isPublic = this.data.currentFolder?.type?.includes('public');
this.setAllActions(false);

const isSingleItem = this.selectedItems.length === 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@
rootUrl = '/private';
}

if (this.item.isFolder) {
if (this.item.isFolder || (this.item as FolderVO).folderId) {
if (this.checkFolderView && this.isFolderViewSet()) {
this.router.navigate([
rootUrl,
Expand All @@ -563,9 +563,24 @@
});
}
if (this.isInSharePreview || this.isInPublicArchive) {
this.router.navigate([this.item.archiveNbr, this.item.folder_linkId], {
relativeTo: this.route.parent,
});
const params = this.route.snapshot.params;
const token = params.token;
const itemId = (this.item as FolderVO).folderId;

Check warning on line 568 in src/app/file-browser/components/file-list-item/file-list-item.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/file-browser/components/file-list-item/file-list-item.component.ts#L566-L568

Added lines #L566 - L568 were not covered by tests
if (token && itemId) {
this.router.navigate([

Check warning on line 570 in src/app/file-browser/components/file-list-item/file-list-item.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/file-browser/components/file-list-item/file-list-item.component.ts#L570

Added line #L570 was not covered by tests
'/share/view/v2-file-list',
'folder',
token,
itemId,
]);
} else {
this.router.navigate(

Check warning on line 577 in src/app/file-browser/components/file-list-item/file-list-item.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/file-browser/components/file-list-item/file-list-item.component.ts#L577

Added line #L577 was not covered by tests
[this.item.archiveNbr, this.item.folder_linkId],
{
relativeTo: this.route.parent,
},
);
}
} else {
this.router.navigate([
rootUrl,
Expand All @@ -580,9 +595,18 @@
) {
this.router.navigate(['/shares/record', this.item.archiveNbr]);
} else {
this.router.navigate(['record', this.item.archiveNbr], {
relativeTo: this.route,
});
if (this.item.archiveNumber) {
this.router.navigate(

Check warning on line 599 in src/app/file-browser/components/file-list-item/file-list-item.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/file-browser/components/file-list-item/file-list-item.component.ts#L599

Added line #L599 was not covered by tests
['record', 'v2', (this.item as RecordVO).recordId],
{
relativeTo: this.route,
},
);
} else if (this.item.archiveNbr) {
this.router.navigate(['record', this.item.archiveNbr], {

Check warning on line 606 in src/app/file-browser/components/file-list-item/file-list-item.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/file-browser/components/file-list-item/file-list-item.component.ts#L606

Added line #L606 was not covered by tests
relativeTo: this.route,
});
}
}
}

Expand Down Expand Up @@ -1120,7 +1144,7 @@

private showFolderIcon(): boolean {
return (
this.item.isFolder &&
(this.item.isFolder || this.item.folderId) &&
this.folderContentsType !== FolderContentsType.NORMAL
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<pr-file-list-controls
[hidden]="!showSidebar"
(refreshView)="refreshView()"
#controls
></pr-file-list-controls>
<pr-folder-description
[folder]="currentFolder"
*ngIf="showFolderDescription && !isRootFolder"
></pr-folder-description>
<div
class="file-list-scroll"
[class.is-sorting]="controls?.isSorting$ | async"
#scroll
>
<div
class="empty-message"
*ngIf="!currentFolder?.ChildItemVOs || !currentFolder?.ChildItemVOs.length"
>
This folder is empty
</div>
<pr-file-list-item
*ngFor="let item of currentFolder?.ChildItemVOs"
[@ngIfScaleAnimationDynamic]="
item?.isPendingAction || item?.isNewlyCreated ? 'animate' : 'static'
"
[item]="item"
[folderView]="folderView"
[multiSelect]="isMultiSelectEnabled"
[allowNavigation]="allowNavigation"
[isSelected]="showSidebar ? selectedItems.has(item) : false"
[canSelect]="showSidebar"
[showFolderThumbnails]="showFolderThumbnails"
(itemClicked)="onItemClick($event)"
(itemVisible)="onItemVisible($event)"
(refreshView)="refreshView()"
></pr-file-list-item>
</div>
<pr-sidebar class="adjust-for-announcement" *ngIf="showSidebar"></pr-sidebar>
<div [@slideUpAnimation]="o.isActivated ? o.activatedRoute : ''">
<router-outlet #o="outlet"></router-outlet>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@import 'variables';

:host {
width: 100%;
@include has-breadcrumbs;

&.no-padding {
padding-top: 0px;
}

&.file-list-centered {
@include public-centered;
}

.file-list-scroll {
opacity: 1;

&.is-sorting {
opacity: 0.5;
cursor: wait;
* {
pointer-events: none;
}
}
}
}

.empty-message {
padding: 20px 10px;
text-align: center;
}

.file-list-drag-target {
width: calc(100% - #{$sidebar-width});
border: 5px solid $PR-orange;
position: fixed;
top: $file-list-controls-height;
left: 0;
right: $sidebar-width;
bottom: 0;
z-index: -1;
opacity: 0;

font-weight: 700;
display: flex;
justify-content: center;
align-items: center;

&.active {
z-index: 10;
opacity: 1;
transition: opacity 0.25s $tweaked-ease;
background: rgba(white, 0.7);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* @format */
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DataService } from '@shared/services/data/data.service';
import { AccountService } from '@shared/services/account/account.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Location } from '@angular/common';
import { DragService } from '@shared/services/drag/drag.service';
import { FolderViewService } from '@shared/services/folder-view/folder-view.service';
import { DeviceService } from '@shared/services/device/device.service';
import { EventService } from '@shared/services/event/event.service';
import { of, Subject } from 'rxjs';
import { FolderVO } from '@models/folder-vo';
import { RouterTestingModule } from '@angular/router/testing';
import { CdkPortal } from '@angular/cdk/portal';
import { FileListItemComponent } from '@fileBrowser/components/file-list-item/file-list-item.component';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { FileListV2Component } from './file-list-v2.component';

describe('FileListV2Component', () => {
let component: FileListV2Component;
let fixture: ComponentFixture<FileListV2Component>;

const folderViewServiceMock = {
folderView: 'List',
viewChange: new Subject(),
};

const dragServiceMock = {
events: jasmine.createSpy('events').and.returnValue(of({ type: 'start' })),
};

const deviceServiceMock = {
isMobileWidth: jasmine.createSpy('isMobileWidth').and.returnValue(false),
};

const accountServiceMock = {
archiveChange: new Subject(),
};

const eventServiceMock = {
dispatch: jasmine.createSpy('dispatch'),
};

const dataServiceMock = {
setCurrentFolder: jasmine.createSpy('setCurrentFolder'),
folderUpdate: of(new FolderVO({})),
selectedItems$: jasmine
.createSpy('selectedItems$')
.and.returnValue(of(new Set())),
multiSelectChange: of(true),
itemToShow$: jasmine.createSpy('itemToShow$').and.returnValue(of(null)),
fetchLeanItems: jasmine.createSpy('fetchLeanItems'),
onSelectEvent: jasmine.createSpy('onSelectEvent'),
};

const routerMock = {
navigate: jasmine.createSpy('navigate'),
events: new Subject(),
url: '/folder',
};

const routeMock = {
snapshot: {
data: {
currentFolder: new FolderVO({
type: 'type.folder.root',
}),
showSidebar: true,
fileListCentered: false,
isPublicArchive: false,
},
queryParamMap: {
has: jasmine.createSpy('has').and.returnValue(false),
get: jasmine.createSpy('get').and.returnValue(null),
},
},
};

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule, NoopAnimationsModule],
declarations: [FileListV2Component, FileListItemComponent, CdkPortal],
providers: [
{ provide: DataService, useValue: dataServiceMock },
{ provide: AccountService, useValue: accountServiceMock },
{ provide: ActivatedRoute, useValue: routeMock },
{ provide: Router, useValue: routerMock },
{ provide: Location, useValue: {} }, // Use empty mock for Location
{ provide: FolderViewService, useValue: folderViewServiceMock },
{ provide: DragService, useValue: dragServiceMock },
{ provide: DeviceService, useValue: deviceServiceMock },
{ provide: EventService, useValue: eventServiceMock },
],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(FileListV2Component);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create the component', () => {
expect(component).toBeTruthy();
});
});
Loading