Skip to content

Commit

Permalink
feat(resource): add document viewer with download (DSP-1791) (#485)
Browse files Browse the repository at this point in the history
* chore(deps): add ng2-pdf-viewer

* chore(deps): bump dsp-js version

* chore(deps): add ng2-pdf-viewer

* refactor(resource): better file representation handling

* refactor(resource): update still image viewer

same view as for documents

* feat(resource): document viewer

* feat(resource): document viewer

* style(resource): same style in document and still image viewer

* test(resource): fix tests

* style(resource): bigger representation viewer
  • Loading branch information
kilchenmann committed Jul 19, 2021
1 parent e12f196 commit ce51bce
Show file tree
Hide file tree
Showing 19 changed files with 896 additions and 1,294 deletions.
1,379 changes: 352 additions & 1,027 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -34,7 +34,7 @@
"@angular/platform-browser-dynamic": "^11.2.9",
"@angular/router": "^11.2.9",
"@ckeditor/ckeditor5-angular": "^1.2.3",
"@dasch-swiss/dsp-js": "^2.6.0",
"@dasch-swiss/dsp-js": "^2.6.1",
"@dasch-swiss/dsp-ui": "^1.6.0",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "5.0.0",
Expand All @@ -49,6 +49,7 @@
"json2typescript": "^1.0.6",
"jsonld": "^5.2.0",
"moment": "^2.27.0",
"ng2-pdf-viewer": "^7.0.1",
"ngx-color-picker": "^11.0.0",
"openseadragon": "^2.4.0",
"rxjs": "~6.5.5",
Expand Down
108 changes: 56 additions & 52 deletions src/app/app.module.ts
Expand Up @@ -18,81 +18,83 @@ import {
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AngularSplitModule } from 'angular-split';
import { PdfViewerModule } from 'ng2-pdf-viewer';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AccountComponent } from './user/account/account.component';
import { AddGroupComponent } from './project/permission/add-group/add-group.component';
import { AddressTemplateComponent } from './project/board/address-template/address-template.component';
import { AddUserComponent } from './project/collaboration/add-user/add-user.component';
import { AttributionTabViewComponent } from './project/board/attribution-tab-view/attribution-tab-view.component';
import { BoardComponent } from './project/board/board.component';
import { CollaborationComponent } from './project/collaboration/collaboration.component';
import { CollectionListComponent } from './user/collection-list/collection-list.component';
import { ContactsTabViewComponent } from './project/board/contacts-tab-view/contacts-tab-view.component';
import { CookiePolicyComponent } from './main/cookie-policy/cookie-policy.component';
import { DashboardComponent } from './user/dashboard/dashboard.component';
import { DatasetTabViewComponent } from './project/board/dataset-tab-view/dataset-tab-view.component';
import { DialogComponent } from './main/dialog/dialog.component';
import { DialogHeaderComponent } from './main/dialog/dialog-header/dialog-header.component';
import { EditListItemComponent } from './project/list/list-item-form/edit-list-item/edit-list-item.component';
import { ErrorComponent } from './main/error/error.component';
import { DialogComponent } from './main/dialog/dialog.component';
import { ExternalLinksDirective } from './main/directive/external-links.directive';
import { InvalidControlScrollDirective } from './main/directive/invalid-control-scroll.directive';
import { ErrorComponent } from './main/error/error.component';
import { FooterComponent } from './main/footer/footer.component';
import { GridComponent } from './main/grid/grid.component';
import { GroupsComponent } from './system/groups/groups.component';
import { GroupsListComponent } from './system/groups/groups-list/groups-list.component';
import { HeaderComponent } from './main/header/header.component';
import { HelpComponent } from './main/help/help.component';
import { InvalidControlScrollDirective } from './main/directive/invalid-control-scroll.directive';
import { ListComponent } from './project/list/list.component';
import { ListInfoFormComponent } from './project/list/list-info-form/list-info-form.component';
import { ListItemComponent } from './project/list/list-item/list-item.component';
import { ListItemFormComponent } from './project/list/list-item-form/list-item-form.component';
import { LoginComponent } from './main/login/login.component';
import { MainComponent } from './main/main.component';
import { SplitPipe } from './main/pipes/split.pipe';
import { SelectLanguageComponent } from './main/select-language/select-language.component';
import { MaterialModule } from './material-module';
import { MembershipComponent } from './user/membership/membership.component';
import { OntologyComponent } from './project/ontology/ontology.component';
import { OntologyFormComponent } from './project/ontology/ontology-form/ontology-form.component';
import { OntologyVisualizerComponent } from './project/ontology/ontology-visualizer/ontology-visualizer.component';
import { AddressTemplateComponent } from './project/board/address-template/address-template.component';
import { AttributionTabViewComponent } from './project/board/attribution-tab-view/attribution-tab-view.component';
import { BoardComponent } from './project/board/board.component';
import { ContactsTabViewComponent } from './project/board/contacts-tab-view/contacts-tab-view.component';
import { DatasetTabViewComponent } from './project/board/dataset-tab-view/dataset-tab-view.component';
import { OrganisationTemplateComponent } from './project/board/organisation-template/organisation-template.component';
import { PasswordFormComponent } from './user/user-form/password-form/password-form.component';
import { PermissionComponent } from './project/permission/permission.component';
import { PersonTemplateComponent } from './project/board/person-template/person-template.component';
import { ProfileComponent } from './user/profile/profile.component';
import { ProjectComponent } from './project/project.component';
import { ProjectFormComponent } from './project/project-form/project-form.component';
import { ProjectsComponent } from './system/projects/projects.component';
import { ProjectsListComponent } from './system/projects/projects-list/projects-list.component';
import { ProjectTabViewComponent } from './project/board/project-tab-view/project-tab-view.component';
import { PropertiesComponent } from './workspace/resource/properties/properties.component';
import { TermsTabViewComponent } from './project/board/terms-tab-view/terms-tab-view.component';
import { UrlTemplateComponent } from './project/board/url-template/url-template.component';
import { AddUserComponent } from './project/collaboration/add-user/add-user.component';
import { CollaborationComponent } from './project/collaboration/collaboration.component';
import { SelectGroupComponent } from './project/collaboration/select-group/select-group.component';
import { ListInfoFormComponent } from './project/list/list-info-form/list-info-form.component';
import { EditListItemComponent } from './project/list/list-item-form/edit-list-item/edit-list-item.component';
import { ListItemFormComponent } from './project/list/list-item-form/list-item-form.component';
import { ListItemComponent } from './project/list/list-item/list-item.component';
import { ListComponent } from './project/list/list.component';
import { OntologyFormComponent } from './project/ontology/ontology-form/ontology-form.component';
import { OntologyVisualizerComponent } from './project/ontology/ontology-visualizer/ontology-visualizer.component';
import { VisualizerComponent } from './project/ontology/ontology-visualizer/visualizer/visualizer.component';
import { OntologyComponent } from './project/ontology/ontology.component';
import { PropertyFormComponent } from './project/ontology/property-form/property-form.component';
import { PropertyInfoComponent } from './project/ontology/property-info/property-info.component';
import { ResourceClassFormComponent } from './project/ontology/resource-class-form/resource-class-form.component';
import { ResourceClassInfoComponent } from './project/ontology/resource-class-info/resource-class-info.component';
import { ResourceComponent } from './workspace/resource/resource.component';
import { AddGroupComponent } from './project/permission/add-group/add-group.component';
import { PermissionComponent } from './project/permission/permission.component';
import { ProjectFormComponent } from './project/project-form/project-form.component';
import { ProjectComponent } from './project/project.component';
import { GroupsListComponent } from './system/groups/groups-list/groups-list.component';
import { GroupsComponent } from './system/groups/groups.component';
import { ProjectsListComponent } from './system/projects/projects-list/projects-list.component';
import { ProjectsComponent } from './system/projects/projects.component';
import { SystemComponent } from './system/system.component';
import { UsersListComponent } from './system/users/users-list/users-list.component';
import { UsersComponent } from './system/users/users.component';
import { AccountComponent } from './user/account/account.component';
import { CollectionListComponent } from './user/collection-list/collection-list.component';
import { DashboardComponent } from './user/dashboard/dashboard.component';
import { MembershipComponent } from './user/membership/membership.component';
import { ProfileComponent } from './user/profile/profile.component';
import { PasswordFormComponent } from './user/user-form/password-form/password-form.component';
import { UserFormComponent } from './user/user-form/user-form.component';
import { UserMenuComponent } from './user/user-menu/user-menu.component';
import { UserComponent } from './user/user.component';
import { PropertiesComponent } from './workspace/resource/properties/properties.component';
import { DocumentComponent } from './workspace/resource/representation/document/document.component';
import { StillImageComponent } from './workspace/resource/representation/still-image/still-image.component';
import { UploadComponent } from './workspace/resource/representation/upload/upload.component';
import { ResourceInstanceFormComponent } from './workspace/resource/resource-instance-form/resource-instance-form.component';
import { ResultsComponent } from './workspace/results/results.component';
import { SelectGroupComponent } from './project/collaboration/select-group/select-group.component';
import { SelectLanguageComponent } from './main/select-language/select-language.component';
import { SelectOntologyComponent } from './workspace/resource/resource-instance-form/select-ontology/select-ontology.component';
import { SelectProjectComponent } from './workspace/resource/resource-instance-form/select-project/select-project.component';
import { SelectPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/select-properties.component';
import { SelectResourceClassComponent } from './workspace/resource/resource-instance-form/select-resource-class/select-resource-class.component';
import { StillImageComponent } from './workspace/resource/representation/still-image/still-image.component';
import { SwitchPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/switch-properties/switch-properties.component';
import { SystemComponent } from './system/system.component';
import { TermsTabViewComponent } from './project/board/terms-tab-view/terms-tab-view.component';
import { UrlTemplateComponent } from './project/board/url-template/url-template.component';
import { UserComponent } from './user/user.component';
import { UserFormComponent } from './user/user-form/user-form.component';
import { UserMenuComponent } from './user/user-menu/user-menu.component';
import { UsersComponent } from './system/users/users.component';
import { UsersListComponent } from './system/users/users-list/users-list.component';
import { VisualizerComponent } from './project/ontology/ontology-visualizer/visualizer/visualizer.component';
import { UploadComponent } from './workspace/resource/representation/upload/upload.component';
import { SplitPipe } from './main/pipes/split.pipe';
import { SelectResourceClassComponent } from './workspace/resource/resource-instance-form/select-resource-class/select-resource-class.component';
import { ResourceComponent } from './workspace/resource/resource.component';
import { ResultsComponent } from './workspace/results/results.component';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand All @@ -116,6 +118,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
DatasetTabViewComponent,
DialogComponent,
DialogHeaderComponent,
DocumentComponent,
EditListItemComponent,
ErrorComponent,
ExternalLinksDirective,
Expand Down Expand Up @@ -160,19 +163,19 @@ export function httpLoaderFactory(httpClient: HttpClient) {
SelectProjectComponent,
SelectPropertiesComponent,
SelectResourceClassComponent,
SplitPipe,
StillImageComponent,
SwitchPropertiesComponent,
SystemComponent,
TermsTabViewComponent,
UploadComponent,
UrlTemplateComponent,
UserComponent,
UserFormComponent,
UserMenuComponent,
UsersComponent,
UsersListComponent,
VisualizerComponent,
UploadComponent,
SplitPipe,
],
imports: [
AppRoutingModule,
Expand All @@ -188,6 +191,7 @@ export function httpLoaderFactory(httpClient: HttpClient) {
FormsModule,
HttpClientModule,
MaterialModule,
PdfViewerModule,
ReactiveFormsModule,
TranslateModule.forRoot({
loader: {
Expand Down
10 changes: 5 additions & 5 deletions src/app/workspace/resource/properties/properties.component.html
Expand Up @@ -78,11 +78,11 @@ <h3 class="label mat-title">
<!-- show property; all in case of showAll === true or only the ones with prop.values -->
<div *ngIf="(showAllProps || ( prop.values && prop.values.length > 0 )) &&
(!prop.propDef['isLinkProperty'] &&
prop.guiDef.propertyIndex !== representationConstants.stillImage &&
prop.guiDef.propertyIndex !== representationConstants.movingImage &&
prop.guiDef.propertyIndex !== representationConstants.audio &&
prop.guiDef.propertyIndex !== representationConstants.document &&
prop.guiDef.propertyIndex !== representationConstants.text)"
prop.propDef.objectType !== representationConstants.stillImage &&
prop.propDef.objectType !== representationConstants.movingImage &&
prop.propDef.objectType !== representationConstants.audio &&
prop.propDef.objectType !== representationConstants.document &&
prop.propDef.objectType !== representationConstants.text)"
[class.border-bottom]="prop.values && !last"
class="property">
<div class="property-label">
Expand Down
9 changes: 2 additions & 7 deletions src/app/workspace/resource/properties/properties.component.ts
Expand Up @@ -32,6 +32,7 @@ import {
} from '@dasch-swiss/dsp-ui';
import { Subscription } from 'rxjs';
import { DspResource } from '../dsp-resource';
import { RepresentationConstants } from '../representation/file-representation';

@Component({
selector: 'app-properties',
Expand Down Expand Up @@ -82,13 +83,7 @@ export class PropertiesComponent implements OnInit, OnChanges, OnDestroy {

valueOperationEventSubscriptions: Subscription[] = []; // array of ValueOperationEvent subscriptions

representationConstants = {
'stillImage': Constants.HasStillImageFileValue,
'movingImage': Constants.HasMovingImageFileValue,
'audio': Constants.HasAudioFileValue,
'document': Constants.HasDocumentFileValue,
'text': Constants.HasTextFileValue
};
representationConstants = RepresentationConstants;

project: ReadProject;
user: ReadUser;
Expand Down
@@ -0,0 +1,39 @@
<div class="pdf-container">
<div class="action horizontal top overlay">
<!-- caption -->
<span class="caption mat-caption">
<input
#queryInp
type="text"
id="searchbox"
name="searchbox"
class="pdf-searchbox"
placeholder="Search in pdf..."
[value]="pdfQuery"
(input)="searchQueryChanged($event.target.value)"
(keyup.enter)="searchQueryChanged(queryInp.value)"
/>
</span>
<span class="fill-remaining-space"></span>
<!-- image action tools e.g. zoom, rotate and flip -->
<span>
<!-- zoom buttons -->
<button mat-icon-button id="DSP_PDF_ZOOM_OUT" matTooltip="Zoom out" (click)="zoomFactor = zoomFactor - 0.2">
<mat-icon>remove_circle_outline</mat-icon>
</button>
<button mat-icon-button id="DSP_PDF_HOME" matTooltip="Reset zoom" (click)="zoomFactor = 1.0">
<mat-icon>adjust</mat-icon>
</button>
<button mat-icon-button id="DSP_PDF_ZOOM_IN" matTooltip="Zoom in" (click)="zoomFactor = zoomFactor + 0.2">
<mat-icon>add_circle_outline</mat-icon>
</button>
<a [href]="document.fileValue.fileUrl" download mat-icon-button id="DSP_PDF_DOWNLOAD" matTooltip="Open pdf in new tab">
<mat-icon>launch</mat-icon>
</a>
</span>
</div>

<pdf-viewer [src]="document.fileValue.fileUrl" [original-size]="false" [autoresize]="true" [show-all]="true"
[show-borders]="true" [zoom]="zoomFactor" [zoom-scale]="'page-width'">
</pdf-viewer>
</div>
@@ -0,0 +1,33 @@
@import "../../../../../assets/style/config";

// sizes
$max-width: 800px;
$panelSize: 40px;

$osd-height: 460px;

// colors
$dark: #000;
$bright: #ccc;

:host {

.pdf-container {
color: $bright;
background-color: $dark;
height: 100%;
}

.pdf-searchbox {
border-radius: $border-radius;
border: none;
padding: 4px;

&:active {
border: none;
}
}


}

0 comments on commit ce51bce

Please sign in to comment.