Skip to content

Commit

Permalink
MOBILE-2256 privatefiles: Remove private files
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonso-salces committed Sep 25, 2024
1 parent 45008e4 commit 491cc8d
Show file tree
Hide file tree
Showing 16 changed files with 490 additions and 9 deletions.
7 changes: 6 additions & 1 deletion scripts/langindex.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@
"addon.blog.associatewithmodule": "blog",
"addon.blog.associations": "blog",
"addon.blog.blog": "blog",
"addon.blog.blogentries": "blog",
"addon.blog.blogdeleteconfirm": "blog",
"addon.blog.blogentries": "blog",
"addon.blog.entrybody": "blog",
"addon.blog.entrytitle": "blog",
"addon.blog.errorloadentries": "local_moodlemobileapp",
Expand Down Expand Up @@ -1566,6 +1566,8 @@
"core.confirmleaveunknownchanges": "local_moodlemobileapp",
"core.confirmloss": "local_moodlemobileapp",
"core.confirmopeninbrowser": "local_moodlemobileapp",
"core.confirmremoveselectedfile": "local_moodlemobileapp",
"core.confirmremoveselectedfiles": "local_moodlemobileapp",
"core.connectionlost": "local_moodlemobileapp",
"core.considereddigitalminor": "moodle",
"core.contactsupport": "local_moodlemobileapp",
Expand Down Expand Up @@ -1809,6 +1811,7 @@
"core.expand": "moodle",
"core.explanationdigitalminor": "moodle",
"core.favourites": "moodle",
"core.filedeletedsuccessfully": "local_moodlemobileapp",
"core.filename": "repository",
"core.filenameexist": "local_moodlemobileapp",
"core.filenotfound": "resource",
Expand Down Expand Up @@ -2390,6 +2393,7 @@
"core.reminders.units": "qtype_numerical",
"core.reminders.value": "local_moodlemobileapp",
"core.remove": "moodle",
"core.removedownloadeddata": "local_moodlemobileapp",
"core.removefiles": "local_moodlemobileapp",
"core.reportbuilder.filtersapplied": "local_moodlemobileapp",
"core.reportbuilder.hidecolumns": "local_moodlemobileapp",
Expand Down Expand Up @@ -2431,6 +2435,7 @@
"core.selectacategory": "moodle",
"core.selectacourse": "moodle",
"core.selectagroup": "moodle",
"core.selectall": "local_moodlemobileapp",
"core.send": "message",
"core.sending": "chat",
"core.serverconnection": "local_moodlemobileapp",
Expand Down
30 changes: 30 additions & 0 deletions src/addons/privatefiles/components/file-actions/file-actions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<header>
<ion-item button="false" detail="false" class="ion-text-wrap">
<ion-thumbnail slot="start">
<img [src]="icon" alt="" role="presentation" />
</ion-thumbnail>

<ion-label>{{ filename }}</ion-label>

<ion-button shape="round" size="default" slot="end" fill="clear" [ariaLabel]="'core.close' | translate"
(click)="close({ status: 'cancel' })">
<ion-icon slot="icon-only" name="close" aria-label="hidden" />
</ion-button>
</ion-item>
</header>

<hr>

<ion-list>
@if (isDownloaded) {
<ion-item button detail="false" lines="none" (click)="close({ status: 'deleteOffline' })">
<ion-icon slot="start" name="fam-cloud-x" aria-hidden="true" />
<ion-label>{{ 'core.removedownloadeddata' | translate }}</ion-label>
</ion-item>
}

<ion-item button detail="false" (click)="close({ status: 'deleteOnline' })" lines="none">
<ion-icon slot="start" name="fas-trash" aria-hidden="true" color="danger" />
<ion-label> {{ 'core.delete' | translate }} </ion-label>
</ion-item>
</ion-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
hr {
background: var(--gray-300);
}

ion-thumbnail {
--size: 1.5rem;
margin-inline-end: 0.5rem;
}
41 changes: 41 additions & 0 deletions src/addons/privatefiles/components/file-actions/file-actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { CoreSharedModule } from '@/core/shared.module';
import { ChangeDetectionStrategy, Component, ElementRef, Input } from '@angular/core';
import { CoreModalComponent } from '@classes/modal-component';

@Component({
selector: 'addon-privatefiles-file-actions',
styleUrl: './file-actions.scss',
templateUrl: 'file-actions.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CoreSharedModule],
})
export class AddonPrivateFilesFileActionsComponent extends CoreModalComponent<AddonPrivateFilesFileActionsComponentParams> {

@Input({ required: false }) isDownloaded = false;
@Input({ required: true }) filename = '';
@Input({ required: true }) icon = '';

constructor(elementRef: ElementRef<HTMLElement>) {
super(elementRef);
}

}

export type AddonPrivateFilesFileActionsComponentParams = {
status: 'cancel' | 'deleteOnline' | 'deleteOffline' | 'download';
};
53 changes: 53 additions & 0 deletions src/addons/privatefiles/components/file/file.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<ion-card class="card-file">

@if (file) {
<ion-item button [ngClass]="{ 'file-selected': showCheckbox && selected }" class="ion-text-wrap item-file" [detail]="false">

@if (showCheckbox) {
<ion-checkbox labelPlacement="start" [(ngModel)]="selected" (ngModelChange)="onSelectedFileChange.emit($event)" />
} @else {
<ion-thumbnail slot="start" (click)="download($event, true)">
<img [src]="fileIcon" alt="" role="presentation" />
</ion-thumbnail>
}

<ion-label (click)="download($event, true)">
<p class="item-heading">
{{fileName}}

@if (state === statusDownloaded) {
<ion-icon class="core-icon-downloaded" color="success" name="fam-cloud-done"
[attr.aria-label]="'core.downloaded' | translate" role="status" />
}
</p>


<p *ngIf="fileSizeReadable || showTime">
<ng-container *ngIf="fileSizeReadable">{{ fileSizeReadable }}</ng-container>
<ng-container *ngIf="fileSizeReadable && showTime"> · </ng-container>
<ng-container *ngIf="showTime">{{ timemodified * 1000 | coreFormatDate }}</ng-container>
</p>
</ion-label>
<div slot="end" class="flex-row">
<ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile($event, true)" [title]="openButtonLabel | translate">
<ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true" />
</ion-button>

@if (!showCheckbox) {

@if (!isDownloaded && state !== statusDownloaded) {
<core-download-refresh [status]="state" [enabled]="canDownload" [loading]="isDownloading" [canTrustDownload]="!alwaysDownload"
(action)="download()" />
}

@if (canDeleteFiles) {
<ion-button (click)="openMenuClick()" fill="clear">
<ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true" />
</ion-button>
}
}
</div>
</ion-item>
}

</ion-card>
14 changes: 14 additions & 0 deletions src/addons/privatefiles/components/file/file.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
:host {
ion-checkbox {
flex: none;
width: 3rem;
}

ion-item.item.item-file {
&.file-selected {
--ion-item-background: var(--primary-tint);
}

--inner-border-width: 0 !important;
}
}
56 changes: 56 additions & 0 deletions src/addons/privatefiles/components/file/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { DownloadStatus } from '@/core/constants';
import { CoreSharedModule } from '@/core/shared.module';
import { toBoolean } from '@/core/transforms/boolean';
import { AddonPrivateFiles } from '@addons/privatefiles/services/privatefiles';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { CoreFileComponent } from '@components/file/file';
import { CoreSites } from '@services/sites';

@Component({
selector: 'addon-privatefiles-file',
templateUrl: 'file.html',
standalone: true,
styleUrls: ['file.scss'],
imports: [CoreSharedModule],
})
export class AddonPrivateFilesFileComponent extends CoreFileComponent implements OnInit, OnDestroy {

@Input({ transform: toBoolean }) showCheckbox = true; // Show checkbox
@Input({ transform: toBoolean, required: false }) selected = false; // Selected file.

@Output() onSelectedFileChange: EventEmitter<boolean>; // Will notify when the checkbox value changes.
@Output() onOpenMenuClick: EventEmitter<CoreFileComponent>; // Will notify when menu clicked.

statusDownloaded = DownloadStatus.DOWNLOADED;
canDeleteFiles = false;

constructor() {
super();
this.onSelectedFileChange = new EventEmitter<boolean>();
this.onOpenMenuClick = new EventEmitter<CoreFileComponent>();
}

async ngOnInit(): Promise<void> {
const siteId = CoreSites.getCurrentSiteId();
this.canDeleteFiles = await AddonPrivateFiles.canDeletePrivateFiles(siteId);
await super.ngOnInit();
}

openMenuClick(): void {
this.onOpenMenuClick.emit(this);
}

}
37 changes: 34 additions & 3 deletions src/addons/privatefiles/pages/index/index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
@if (selectFilesEnabled()) {
<ion-button fill="clear" [ariaLabel]="'core.close' | translate" (click)="cancelFileSelection()">
<ion-icon slot="icon-only" name="fas-xmark" aria-hidden="true" />
</ion-button>
} @else {
<ion-back-button [text]="'core.back' | translate" />
}
</ion-buttons>
<ion-title>
<h1>{{ title }}</h1>
<h1>{{ selectFilesEnabled() ? (selectedFiles.length + ' ' + title) : title }}</h1>
</ion-title>
<ion-buttons slot="end">
@if (selectFilesEnabled()) {
<ion-button fill="clear" (click)="deleteSelectedFiles(true)" [ariaLabel]="'core.delete' | translate" color="danger">
<ion-icon slot="icon-only" name="fas-trash" aria-hidden="true" />
</ion-button>
}
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="limited-width">
Expand All @@ -28,6 +41,7 @@ <h1>{{ title }}</h1>
<!-- Display info about space used and space left. -->
<ion-card class="core-info-card" *ngIf="userQuota && filesInfo && filesInfo.filecount > 0">
<ion-item>
<ion-icon slot="start" aria-label="hidden" name="fas-cloud" />
<ion-label>
{{ 'core.quotausage' | translate:{$a: {used: spaceUsed, total: userQuotaReadable} } }}
</ion-label>
Expand All @@ -42,7 +56,14 @@ <h1>{{ title }}</h1>
<ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.folder' | translate" />
<ion-label>{{file.filename}}</ion-label>
</ion-item>
<core-file *ngIf="!file.isdir" [file]="file" [component]="component" [componentId]="file.contextid" />

@if (!file.isdir) {
<addon-privatefiles-file [file]="file" [component]="component" [componentId]="file.contextid"
(onOpenMenuClick)="root === 'my' && openManagementFileMenu($event, file)"
(longPress)="root === 'my' && enableMultipleSelection(file)" [showCheckbox]="root === 'my' && selectFilesEnabled()"
(onSelectedFileChange)="root === 'my' && selectedFileValueChanged($event, file)" showDownloadStatus="true"
[selected]="file.selected" />
}
</ng-container>
</ion-list>

Expand All @@ -51,10 +72,20 @@ <h1>{{ title }}</h1>
</core-loading>

<!-- Upload a private file. -->
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="showUpload && root !== 'site' && !path">
@if (showUpload && root !== 'site' && !path && !selectFilesEnabled()) {
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
<ion-fab-button (click)="uploadFile()" [attr.aria-label]="'core.fileuploader.uploadafile' | translate">
<ion-icon name="fas-plus" aria-hidden="true" />
<span class="sr-only">{{ 'core.fileuploader.uploadafile' | translate }}</span>
</ion-fab-button>
</ion-fab>
}
</ion-content>

@if (selectFilesEnabled()) {
<div class="ion-padding addons-privatefiles-index-select-all">
<ion-checkbox labelPlacement="end" [(ngModel)]="selectAll" (ngModelChange)="onSelectAllChanges($event)">
{{ 'core.selectall' | translate }}
</ion-checkbox>
</div>
}
10 changes: 10 additions & 0 deletions src/addons/privatefiles/pages/index/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


:host {
--addons-privatefiles-index-select-all-shadow: 0px 8px 10px 0px #282828;

.addons-privatefiles-index-select-all {
box-shadow: var(--addons-privatefiles-index-select-all-shadow);
z-index: 3;
}
}
Loading

0 comments on commit 491cc8d

Please sign in to comment.