Skip to content

Commit

Permalink
Merge pull request #3 from opf/angular-cli
Browse files Browse the repository at this point in the history
Adapt to angular CLI
  • Loading branch information
ulferts authored Jun 25, 2018
2 parents 1457430 + 0c8fd96 commit 4e4f345
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 170 deletions.
3 changes: 2 additions & 1 deletion app/assets/stylesheets/avatars/_openproject_avatars.sass
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
width: 64px

.avatars--local-avatar-preview
width: 64px
width: 128px
height: 128px
border-radius: 50%

.avatars--current-gravatar
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/avatars/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def service_request(type:)
service = ::Avatars::UpdateService.new @user

if type == :update
service.replace params[:avatar]
service.replace params[:file]
elsif type == :destroy
service.destroy
end
Expand Down
3 changes: 1 addition & 2 deletions app/views/avatars/users/_local_avatars.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,5 @@
</div>
</div>
</div>
<avatar-upload-form target="<%= @target_avatar_path %>" method="PUT">
</avatar-upload-form>
<avatar-upload-form target="<%= @target_avatar_path %>" method="PUT"></avatar-upload-form>
</fieldset>
1 change: 1 addition & 0 deletions config/locales/js-en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ en:
button_update: 'Update'
avatars:
label_choose_avatar: "Choose Avatar from file"
uploading_avatar: "Uploading your avatar."
text_upload_instructions: |
Upload your own custom avatar of 128 by 128 pixels. Larger files will be resized and cropped to match.
A preview of your avatar will be shown before uploading, once you selected an image.
Expand Down
112 changes: 0 additions & 112 deletions frontend/app/components/avatars/avatar-upload-form.component.ts

This file was deleted.

44 changes: 0 additions & 44 deletions frontend/app/templates/plugin-avatars/avatar-upload-form.html

This file was deleted.

125 changes: 125 additions & 0 deletions frontend/module/avatar-upload-form/avatar-upload-form.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
import {Component, ElementRef, OnInit, ViewChild} from "@angular/core";
import {I18nService} from "core-app/modules/common/i18n/i18n.service";
import {OpenProjectFileUploadService, UploadBlob} from "core-components/api/op-file-upload/op-file-upload.service";
import {NotificationsService} from "core-app/modules/common/notifications/notifications.service";
import {UploadFile} from "core-components/api/op-file-upload/op-file-upload.service";
import {ImageHelpers} from "core-app/helpers/images/resizer";

@Component({
selector: 'avatar-upload-form',
templateUrl: './avatar-upload-form.html'
})
export class AvatarUploadFormComponent implements OnInit {
// Form targets
public form:any;
public target:string;
public method:string;

// File
public avatarFile:any;
public avatarPreviewUrl:any;
public busy:boolean = false;
public fileInvalid = false;

@ViewChild('avatarFilePicker') public avatarFilePicker:ElementRef;

// Text
public text = {
label_choose_avatar: this.I18n.t('js.avatars.label_choose_avatar'),
upload_instructions: this.I18n.t('js.avatars.text_upload_instructions'),
error_too_large: this.I18n.t('js.avatars.error_image_too_large'),
wrong_file_format: this.I18n.t('js.avatars.wrong_file_format'),
button_update: this.I18n.t('js.button_update'),
uploading: this.I18n.t('js.avatars.uploading_avatar'),
preview: this.I18n.t('js.label_preview')
};

public constructor(protected I18n:I18nService,
protected elementRef:ElementRef,
protected notificationsService:NotificationsService,
protected opFileUpload:OpenProjectFileUploadService) {
}

public ngOnInit() {
const element = this.elementRef.nativeElement;
this.target = element.getAttribute('target');
this.method = element.getAttribute('method');
}

public onFilePickerChanged(_evt:Event) {
const files:UploadFile[] = Array.from(this.avatarFilePicker.nativeElement.files);
if (files.length === 0) {
return;
}

const file = files[0];
if (['image/jpeg', 'image/png', 'image/gif'].indexOf(file.type) === -1) {
this.fileInvalid = true;
return;
}

ImageHelpers.resizeFile(128, file).then(([dataURL, blob]) => {
// Create resized file
blob.name = file.name;
this.avatarFile = blob;
this.avatarPreviewUrl = dataURL;
});
}

public uploadAvatar(evt:Event) {
evt.preventDefault();
this.busy = true;
const upload = this.opFileUpload.uploadSingle(this.target, this.avatarFile, this.method, 'text');
this.notificationsService.addWorkPackageUpload(this.text.uploading, [upload]);

upload[1].subscribe(
(evt:any) => {
switch (evt.type) {
case 0: // Sent
return;

case 4:
this.avatarFile.progress = 100;
this.busy = false;
window.location.reload();
return;

default:
// Sent or unknown event
return;
}
},
(error:any) => {
this.notificationsService.addError(error.error);
this.busy = false;
}
);
}
}
32 changes: 32 additions & 0 deletions frontend/module/avatar-upload-form/avatar-upload-form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="form--field">
<label class="form--label"
[ngClass]="{ '-error': fileInvalid }"
[textContent]="text.label_choose_avatar"
for="avatar_file_input">
</label>
<div class="form--field-container">
<input #avatarFilePicker
type="file"
accept="image/jpeg,image/png,image/gif"
id="avatar_file_input"
name="avatar_file_input"
(change)="onFilePickerChanged($event)" />
</div>
<div class="form--field-instructions">
<span [textContent]="text.upload_instructions"></span>
<div class="avatars--error-pane">
<span *ngIf="fileInvalid" [textContent]="text.wrong_file_format"></span>
</div>
</div>
</div>
<fieldset class="preview" *ngIf="avatarPreviewUrl">
<legend class="preview--legend" [textContent]="text.preview"></legend>
<img [src]="avatarPreviewUrl" class="avatars--local-avatar-preview" />
</fieldset>

<button type="submit"
(click)="uploadAvatar($event)"
[attr.disabled]="!avatarFile || busy || undefined"
[textContent]="text.button_update"
class="button -highlight -with-icon icon-checkmark">
</button>
Loading

0 comments on commit 4e4f345

Please sign in to comment.