MOBILE-4470 attachments: Improve Attachments look and feel

main
Pau Ferrer Ocaña 2024-05-08 14:21:01 +02:00
parent f42ab61f59
commit f9ed1e8153
9 changed files with 62 additions and 44 deletions

View File

@ -597,6 +597,8 @@
"addon.mod_data.timeadded": "data",
"addon.mod_data.timemodified": "data",
"addon.mod_data.usedate": "data",
"addon.mod_data_fields_file.fieldtypelabel": "datafield_file",
"addon.mod_data_fields_picture.fieldtypelabel": "datafield_picture",
"addon.mod_feedback.analysis": "feedback",
"addon.mod_feedback.anonymous": "feedback",
"addon.mod_feedback.anonymous_entries": "feedback",
@ -1812,6 +1814,7 @@
"core.filenameexist": "local_moodlemobileapp",
"core.filenotfound": "resource",
"core.fileuploader.addfiletext": "repository",
"core.fileuploader.attachedfiles": "repository",
"core.fileuploader.audio": "local_moodlemobileapp",
"core.fileuploader.audiotitle": "tiny_recordrtc",
"core.fileuploader.camera": "local_moodlemobileapp",
@ -1834,6 +1837,7 @@
"core.fileuploader.microphonepermissiondenied": "local_moodlemobileapp",
"core.fileuploader.microphonepermissionrestricted": "local_moodlemobileapp",
"core.fileuploader.more": "data",
"core.fileuploader.nofilesattached": "repository",
"core.fileuploader.pauserecording": "local_moodlemobileapp",
"core.fileuploader.photoalbums": "local_moodlemobileapp",
"core.fileuploader.readingfile": "local_moodlemobileapp",

View File

@ -1,6 +1,7 @@
<ng-container *ngIf="editMode && form">
<core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId"
[allowOffline]="true" [courseId]="database?.course" [required]="field.required" />
[allowOffline]="true" [courseId]="database?.course" [required]="field.required"
[title]="'addon.mod_data_fields_file.fieldtypelabel' | translate" />
<core-input-errors *ngIf="error" [errorText]="error" />
</ng-container>

View File

@ -0,0 +1,3 @@
{
"fieldtypelabel": "File"
}

View File

@ -1,6 +1,7 @@
<ng-container *ngIf="editMode && form" [formGroup]="form">
<core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId"
[allowOffline]="true" acceptedTypes="image" [courseId]="database?.course" [required]="field.required" />
[allowOffline]="true" acceptedTypes="image" [courseId]="database?.course" [required]="field.required"
[title]="'addon.mod_data_fields_picture.fieldtypelabel' | translate" />
<core-input-errors *ngIf="error" [errorText]="error" />
<ion-input [label]="'addon.mod_data.alttext' | translate" labelPlacement="stacked" type="text"

View File

@ -0,0 +1,3 @@
{
"fieldtypelabel": "Image"
}

View File

@ -17,6 +17,7 @@
<ion-input labelPlacement="stacked" type="text" [placeholder]="'addon.mod_glossary.concept' | translate"
[(ngModel)]="data.concept" name="concept" [label]="'addon.mod_glossary.concept' | translate" />
</ion-item>
<ion-item>
<ion-label position="stacked">{{ 'addon.mod_glossary.definition' | translate }}</ion-label>
<core-rich-text-editor [control]="definitionControl" (contentChanged)="onDefinitionChange($event)"
@ -24,8 +25,8 @@
[componentId]="cmId" [autoSave]="true" contextLevel="module" [contextInstanceId]="cmId" elementId="definition_editor"
[draftExtraParams]="editorExtraParams" />
</ion-item>
<ion-item *ngIf="categories.length > 0">
<ion-item *ngIf="categories.length > 0">
<ion-select labelPlacement="stacked" [(ngModel)]="data.categories" multiple="true" interface="action-sheet"
[placeholder]="'addon.mod_glossary.categories' | translate" name="categories" [cancelText]="'core.cancel' | translate"
[interfaceOptions]="{header: 'addon.mod_glossary.categories' | translate}"
@ -35,18 +36,15 @@
</ion-select-option>
</ion-select>
</ion-item>
<ion-item *ngIf="showAliases">
<ion-item *ngIf="showAliases">
<ion-textarea labelPlacement="stacked" [(ngModel)]="data.aliases" rows="1" [core-auto-rows]="data.aliases" name="aliases"
[label]="'addon.mod_glossary.aliases' | translate" />
</ion-item>
<ion-item-divider>
<ion-label>
<h2>{{ 'addon.mod_glossary.attachment' | translate }}</h2>
</ion-label>
</ion-item-divider>
<core-attachments [files]="data.attachments" [component]="component" [componentId]="glossary.coursemodule" [allowOffline]="true"
[courseId]="courseId" />
[courseId]="courseId" [title]="'addon.mod_glossary.attachment' | translate" />
<ng-container *ngIf="glossary.usedynalink">
<ion-item-divider>
<ion-label>
@ -69,6 +67,7 @@
</ion-toggle>
</ion-item>
</ng-container>
<ion-button class="ion-margin" expand="block" [disabled]="!data.concept || !data.definition" (click)="save()">
{{ 'core.save' | translate }}
</ion-button>

View File

@ -55,6 +55,7 @@ export class CoreAttachmentsComponent implements OnInit {
@Input() acceptedTypes?: string; // List of supported filetypes. If undefined, all types supported.
@Input() required?: boolean; // Whether to display the required mark.
@Input() courseId?: number; // Course ID.
@Input() title = Translate.instant('core.fileuploader.attachedfiles'); // Title to display.
maxSizeReadable?: string;
maxSubmissionsReadable?: string;

View File

@ -1,38 +1,42 @@
<core-loading [hideUntil]="loaded" [fullscreen]="false">
<ion-item class="ion-text-wrap">
<ion-label>
<span *ngIf="maxSubmissionsReadable">
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
</span>
<span *ngIf="!maxSubmissionsReadable">{{ 'core.maxfilesize' | translate:{$a: maxSizeReadable} }}</span>
<span [core-mark-required]="required" class="core-mark-required"></span>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
<ion-label>
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>
<ul class="list-with-style">
<li *ngFor="let typeInfo of fileTypes.info">
<strong *ngIf="typeInfo.name">{{typeInfo.name}} </strong>{{typeInfo.extlist}}
</li>
</ul>
</ion-label>
</ion-item>
<div *ngFor="let file of files; let index=index">
<!-- Files already attached to the submission, either in online or in offline. -->
<core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [canDelete]="true"
(onDelete)="delete(index, true)" [canDownload]="!file.offline" />
<ion-card>
<ion-item class="ion-text-wrap">
<ion-label>
<p class="item-heading">{{ title }} <span [core-mark-required]="required" class="core-mark-required"></span></p>
<span *ngIf="maxSubmissionsReadable">
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
</span>
<span *ngIf="!maxSubmissionsReadable">{{ 'core.maxfilesize' | translate:{$a: maxSizeReadable} }}</span>
</ion-label>
<ion-button slot="end" (click)="add()" [attr.aria-label]="'core.fileuploader.addfiletext' | translate"
*ngIf="unlimitedFiles || (maxSubmissions !== undefined && maxSubmissions >= 0 && files && files.length < maxSubmissions)">
<ion-icon name="fas-plus" slot="icon-only" aria-hidden="true" />
</ion-button>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
<ion-label>
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>
<ul class="list-with-style">
<li *ngFor="let typeInfo of fileTypes.info">
<strong *ngIf="typeInfo.name">{{typeInfo.name}} </strong>{{typeInfo.extlist}}
</li>
</ul>
</ion-label>
</ion-item>
<ng-container *ngFor="let file of files; let index=index">
<!-- Files already attached to the submission, either in online or in offline. -->
<core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [canDelete]="true"
(onDelete)="delete(index, true)" [canDownload]="!file.offline" />
<!-- Files added to draft but not attached to submission yet. -->
<core-local-file *ngIf="file.name" [file]="file" [manage]="true" (onDelete)="delete(index, false)"
(onRename)="renamed(index, $event)" />
</div>
<!-- Files added to draft but not attached to submission yet. -->
<core-local-file *ngIf="file.name" [file]="file" [manage]="true" (onDelete)="delete(index, false)"
(onRename)="renamed(index, $event)" />
</ng-container>
<!-- Button to add more files. -->
<ion-button expand="block"
*ngIf="unlimitedFiles || (maxSubmissions !== undefined && maxSubmissions >= 0 && files && files.length < maxSubmissions)"
class="ion-text-wrap ion-margin" (click)="add()">
<ion-icon name="fas-plus" slot="start" aria-hidden="true" />
{{ 'core.fileuploader.addfiletext' | translate }}
</ion-button>
<ion-item class="ion-text-wrap" *ngIf="!files || !files.length">
<ion-label>
<p>{{ 'core.fileuploader.nofilesattached' | translate }}</p>
</ion-label>
</ion-item>
</ion-card>
</core-loading>

View File

@ -1,5 +1,6 @@
{
"addfiletext": "Add file",
"attachedfiles": "Attached files",
"audio": "Audio",
"audiotitle": "Record audio",
"camera": "Camera",
@ -22,6 +23,7 @@
"microphonepermissiondenied": "Permission to access the microphone has been denied.",
"microphonepermissionrestricted": "Microphone access is restricted.",
"more": "More",
"nofilesattached": "No files attached",
"pauserecording": "Pause recording",
"photoalbums": "Photo albums",
"readingfile": "Reading file",