Skip to content

Commit 9c4965e

Browse files
MOBILE-2256 privatefiles: Remove private files
1 parent 45008e4 commit 9c4965e

File tree

16 files changed

+487
-10
lines changed

16 files changed

+487
-10
lines changed

scripts/langindex.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@
9090
"addon.blog.associatewithmodule": "blog",
9191
"addon.blog.associations": "blog",
9292
"addon.blog.blog": "blog",
93-
"addon.blog.blogentries": "blog",
9493
"addon.blog.blogdeleteconfirm": "blog",
94+
"addon.blog.blogentries": "blog",
9595
"addon.blog.entrybody": "blog",
9696
"addon.blog.entrytitle": "blog",
9797
"addon.blog.errorloadentries": "local_moodlemobileapp",
@@ -1566,6 +1566,8 @@
15661566
"core.confirmleaveunknownchanges": "local_moodlemobileapp",
15671567
"core.confirmloss": "local_moodlemobileapp",
15681568
"core.confirmopeninbrowser": "local_moodlemobileapp",
1569+
"core.confirmremoveselectedfile": "local_moodlemobileapp",
1570+
"core.confirmremoveselectedfiles": "local_moodlemobileapp",
15691571
"core.connectionlost": "local_moodlemobileapp",
15701572
"core.considereddigitalminor": "moodle",
15711573
"core.contactsupport": "local_moodlemobileapp",
@@ -1809,6 +1811,7 @@
18091811
"core.expand": "moodle",
18101812
"core.explanationdigitalminor": "moodle",
18111813
"core.favourites": "moodle",
1814+
"core.filedeletedsuccessfully": "local_moodlemobileapp",
18121815
"core.filename": "repository",
18131816
"core.filenameexist": "local_moodlemobileapp",
18141817
"core.filenotfound": "resource",
@@ -2390,6 +2393,7 @@
23902393
"core.reminders.units": "qtype_numerical",
23912394
"core.reminders.value": "local_moodlemobileapp",
23922395
"core.remove": "moodle",
2396+
"core.removedownloadeddata": "local_moodlemobileapp",
23932397
"core.removefiles": "local_moodlemobileapp",
23942398
"core.reportbuilder.filtersapplied": "local_moodlemobileapp",
23952399
"core.reportbuilder.hidecolumns": "local_moodlemobileapp",
@@ -2431,6 +2435,7 @@
24312435
"core.selectacategory": "moodle",
24322436
"core.selectacourse": "moodle",
24332437
"core.selectagroup": "moodle",
2438+
"core.selectall": "local_moodlemobileapp",
24342439
"core.send": "message",
24352440
"core.sending": "chat",
24362441
"core.serverconnection": "local_moodlemobileapp",
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<header>
2+
<ion-item button="false" detail="false" class="ion-text-wrap">
3+
<ion-thumbnail slot="start">
4+
<img [src]="icon" alt="" role="presentation" />
5+
</ion-thumbnail>
6+
7+
<ion-label>{{ filename }}</ion-label>
8+
9+
<ion-button shape="round" size="default" slot="end" fill="clear" [ariaLabel]="'core.close' | translate"
10+
(click)="close({ status: 'cancel' })">
11+
<ion-icon slot="icon-only" name="close" aria-label="hidden" />
12+
</ion-button>
13+
</ion-item>
14+
</header>
15+
16+
<hr>
17+
18+
<ion-list>
19+
@if (isDownloaded) {
20+
<ion-item button detail="false" lines="none" (click)="close({ status: 'deleteOffline' })">
21+
<ion-icon slot="start" name="fam-cloud-x" aria-hidden="true" />
22+
<ion-label>{{ 'core.removedownloadeddata' | translate }}</ion-label>
23+
</ion-item>
24+
}
25+
26+
<ion-item button detail="false" (click)="close({ status: 'deleteOnline' })" lines="none">
27+
<ion-icon slot="start" name="fas-trash" aria-hidden="true" color="danger" />
28+
<ion-label> {{ 'core.delete' | translate }} </ion-label>
29+
</ion-item>
30+
</ion-list>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
hr {
2+
background: var(--gray-300);
3+
}
4+
5+
ion-thumbnail {
6+
--size: 1.5rem;
7+
margin-inline-end: 0.5rem;
8+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// (C) Copyright 2015 Moodle Pty Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import { CoreSharedModule } from '@/core/shared.module';
16+
import { ChangeDetectionStrategy, Component, ElementRef, Input } from '@angular/core';
17+
import { CoreModalComponent } from '@classes/modal-component';
18+
19+
@Component({
20+
selector: 'addon-privatefiles-file-actions',
21+
styleUrl: './file-actions.scss',
22+
templateUrl: 'file-actions.html',
23+
changeDetection: ChangeDetectionStrategy.OnPush,
24+
standalone: true,
25+
imports: [CoreSharedModule],
26+
})
27+
export class AddonPrivateFilesFileActionsComponent extends CoreModalComponent<AddonPrivateFilesFileActionsComponentParams> {
28+
29+
@Input({ required: false }) isDownloaded = false;
30+
@Input({ required: true }) filename = '';
31+
@Input({ required: true }) icon = '';
32+
33+
constructor(elementRef: ElementRef<HTMLElement>) {
34+
super(elementRef);
35+
}
36+
37+
}
38+
39+
export type AddonPrivateFilesFileActionsComponentParams = {
40+
status: 'cancel' | 'deleteOnline' | 'deleteOffline' | 'download';
41+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<ion-card class="card-file">
2+
3+
@if (file) {
4+
<ion-item button [ngClass]="{ 'file-selected': showCheckbox && selected }" class="ion-text-wrap item-file" [detail]="false">
5+
6+
@if (showCheckbox) {
7+
<ion-checkbox labelPlacement="start" [(ngModel)]="selected" (ngModelChange)="onSelectedFileChange.emit($event)" />
8+
} @else {
9+
<ion-thumbnail slot="start" (click)="download($event, true)">
10+
<img [src]="fileIcon" alt="" role="presentation" />
11+
</ion-thumbnail>
12+
}
13+
14+
<ion-label (click)="download($event, true)">
15+
<p class="item-heading">
16+
{{fileName}}
17+
18+
@if (state === statusDownloaded) {
19+
<ion-icon class="core-icon-downloaded" color="success" name="fam-cloud-done"
20+
[attr.aria-label]="'core.downloaded' | translate" role="status" />
21+
}
22+
</p>
23+
24+
25+
<p *ngIf="fileSizeReadable || showTime">
26+
<ng-container *ngIf="fileSizeReadable">{{ fileSizeReadable }}</ng-container>
27+
<ng-container *ngIf="fileSizeReadable && showTime"> · </ng-container>
28+
<ng-container *ngIf="showTime">{{ timemodified * 1000 | coreFormatDate }}</ng-container>
29+
</p>
30+
</ion-label>
31+
<div slot="end" class="flex-row">
32+
<ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile($event, true)" [title]="openButtonLabel | translate">
33+
<ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true" />
34+
</ion-button>
35+
36+
@if (!showCheckbox) {
37+
38+
@if (state !== statusDownloaded) {
39+
<core-download-refresh [status]="state" [enabled]="canDownload" [loading]="isDownloading" [canTrustDownload]="!alwaysDownload"
40+
(action)="download()" />
41+
}
42+
43+
@if (canDelete) {
44+
<ion-button (click)="openMenuClick()" fill="clear">
45+
<ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true" />
46+
</ion-button>
47+
}
48+
}
49+
</div>
50+
</ion-item>
51+
}
52+
53+
</ion-card>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
:host {
2+
ion-checkbox {
3+
flex: none;
4+
width: 3rem;
5+
}
6+
7+
ion-item.item.item-file {
8+
&.file-selected {
9+
--ion-item-background: var(--primary-tint);
10+
}
11+
12+
--inner-border-width: 0 !important;
13+
}
14+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// (C) Copyright 2015 Moodle Pty Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
import { DownloadStatus } from '@/core/constants';
15+
import { CoreSharedModule } from '@/core/shared.module';
16+
import { toBoolean } from '@/core/transforms/boolean';
17+
import { Component, EventEmitter, Input, OnDestroy, Output } from '@angular/core';
18+
import { CoreFileComponent } from '@components/file/file';
19+
20+
@Component({
21+
selector: 'addon-privatefiles-file',
22+
templateUrl: 'file.html',
23+
standalone: true,
24+
styleUrls: ['file.scss'],
25+
imports: [CoreSharedModule],
26+
})
27+
export class AddonPrivateFilesFileComponent extends CoreFileComponent implements OnDestroy {
28+
29+
@Input({ transform: toBoolean }) showCheckbox = true; // Show checkbox
30+
@Input({ transform: toBoolean, required: false }) selected = false; // Selected file.
31+
32+
@Output() onSelectedFileChange: EventEmitter<boolean>; // Will notify when the checkbox value changes.
33+
@Output() onOpenMenuClick: EventEmitter<CoreFileComponent>; // Will notify when menu clicked.
34+
35+
statusDownloaded = DownloadStatus.DOWNLOADED;
36+
37+
constructor() {
38+
super();
39+
this.onSelectedFileChange = new EventEmitter<boolean>();
40+
this.onOpenMenuClick = new EventEmitter<CoreFileComponent>();
41+
}
42+
43+
openMenuClick(): void {
44+
this.onOpenMenuClick.emit(this);
45+
}
46+
47+
}

src/addons/privatefiles/pages/index/index.html

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
<ion-header>
22
<ion-toolbar>
33
<ion-buttons slot="start">
4+
@if (selectFilesEnabled()) {
5+
<ion-button fill="clear" [ariaLabel]="'core.close' | translate" (click)="cancelFileSelection()">
6+
<ion-icon slot="icon-only" name="fas-xmark" aria-hidden="true" />
7+
</ion-button>
8+
} @else {
49
<ion-back-button [text]="'core.back' | translate" />
10+
}
511
</ion-buttons>
612
<ion-title>
7-
<h1>{{ title }}</h1>
13+
<h1>{{ selectFilesEnabled() ? (selectedFiles.length + ' ' + title) : title }}</h1>
814
</ion-title>
15+
<ion-buttons slot="end">
16+
@if (selectFilesEnabled()) {
17+
<ion-button fill="clear" (click)="deleteSelectedFiles(true)" [ariaLabel]="'core.delete' | translate" color="danger">
18+
<ion-icon slot="icon-only" name="fas-trash" aria-hidden="true" />
19+
</ion-button>
20+
}
21+
</ion-buttons>
922
</ion-toolbar>
1023
</ion-header>
1124
<ion-content class="limited-width">
@@ -28,6 +41,7 @@ <h1>{{ title }}</h1>
2841
<!-- Display info about space used and space left. -->
2942
<ion-card class="core-info-card" *ngIf="userQuota && filesInfo && filesInfo.filecount > 0">
3043
<ion-item>
44+
<ion-icon slot="start" aria-label="hidden" name="fas-cloud" />
3145
<ion-label>
3246
{{ 'core.quotausage' | translate:{$a: {used: spaceUsed, total: userQuotaReadable} } }}
3347
</ion-label>
@@ -42,7 +56,15 @@ <h1>{{ title }}</h1>
4256
<ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.folder' | translate" />
4357
<ion-label>{{file.filename}}</ion-label>
4458
</ion-item>
45-
<core-file *ngIf="!file.isdir" [file]="file" [component]="component" [componentId]="file.contextid" />
59+
60+
@if (!file.isdir) {
61+
<addon-privatefiles-file [file]="file" [component]="component" [componentId]="file.contextid"
62+
(onOpenMenuClick)="root === 'my' && openManagementFileMenu($event, file)"
63+
(longPress)="canDeleteFiles && root === 'my' && enableMultipleSelection(file)"
64+
[showCheckbox]="canDeleteFiles && root === 'my' && selectFilesEnabled()"
65+
(onSelectedFileChange)="root === 'my' && selectedFileValueChanged($event, file)" showDownloadStatus="true"
66+
[selected]="file.selected" [canDelete]="canDeleteFiles && root === 'my'" />
67+
}
4668
</ng-container>
4769
</ion-list>
4870

@@ -51,10 +73,20 @@ <h1>{{ title }}</h1>
5173
</core-loading>
5274

5375
<!-- Upload a private file. -->
54-
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="showUpload && root !== 'site' && !path">
76+
@if (showUpload && root !== 'site' && !path && !selectFilesEnabled()) {
77+
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end">
5578
<ion-fab-button (click)="uploadFile()" [attr.aria-label]="'core.fileuploader.uploadafile' | translate">
5679
<ion-icon name="fas-plus" aria-hidden="true" />
5780
<span class="sr-only">{{ 'core.fileuploader.uploadafile' | translate }}</span>
5881
</ion-fab-button>
5982
</ion-fab>
83+
}
6084
</ion-content>
85+
86+
@if (selectFilesEnabled()) {
87+
<div class="ion-padding addons-privatefiles-index-select-all">
88+
<ion-checkbox labelPlacement="end" [(ngModel)]="selectAll" (ngModelChange)="onSelectAllChanges($event)">
89+
{{ 'core.selectall' | translate }}
90+
</ion-checkbox>
91+
</div>
92+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
:host {
4+
--addons-privatefiles-index-select-all-shadow: 0px 8px 10px 0px #282828;
5+
6+
.addons-privatefiles-index-select-all {
7+
box-shadow: var(--addons-privatefiles-index-select-all-shadow);
8+
z-index: 3;
9+
}
10+
}

0 commit comments

Comments
 (0)