Customize select

This commit is contained in:
Chocobozzz 2017-12-20 14:29:55 +01:00
parent a4b8a4ddcc
commit 15a7387da8
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
13 changed files with 190 additions and 82 deletions

View File

@ -7,7 +7,7 @@
<div class="form-group" *ngIf="isCreation()">
<label for="username">Username</label>
<input
type="text" class="form-control" id="username" placeholder="john"
type="text" id="username" placeholder="john"
formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }"
>
<div *ngIf="formErrors.username" class="form-error">
@ -18,7 +18,7 @@
<div class="form-group">
<label for="email">Email</label>
<input
type="text" class="form-control" id="email" placeholder="mail@example.com"
type="text" id="email" placeholder="mail@example.com"
formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }"
>
<div *ngIf="formErrors.email" class="form-error">
@ -29,7 +29,7 @@
<div class="form-group" *ngIf="isCreation()">
<label for="password">Password</label>
<input
type="password" class="form-control" id="password"
type="password" id="password"
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
>
<div *ngIf="formErrors.password" class="form-error">
@ -39,11 +39,13 @@
<div class="form-group">
<label for="role">Role</label>
<select class="form-control" id="role" formControlName="role">
<option *ngFor="let role of roles" [value]="role.value">
{{ role.label }}
</option>
</select>
<div class="peertube-select-container">
<select id="role" formControlName="role">
<option *ngFor="let role of roles" [value]="role.value">
{{ role.label }}
</option>
</select>
</div>
<div *ngIf="formErrors.role" class="form-error">
{{ formErrors.role }}
@ -52,11 +54,13 @@
<div class="form-group">
<label for="videoQuota">Video quota</label>
<select class="form-control" id="videoQuota" formControlName="videoQuota">
<option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
{{ videoQuotaOption.label }}
</option>
</select>
<div class="peertube-select-container">
<select id="videoQuota" formControlName="videoQuota">
<option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
{{ videoQuotaOption.label }}
</option>
</select>
</div>
<div class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()">
Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br />

View File

@ -10,8 +10,8 @@ input:not([type=submit]) {
display: block;
}
select {
@include peertube-select(340px);
.peertube-select-container {
@include peertube-select-container(340px);
}
input[type=submit] {

View File

@ -1,5 +1,7 @@
// Thanks: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
import { AuthService } from '../../core/auth'
function getParameterByName (name: string, url: string) {
if (!url) url = window.location.href
name = name.replace(/[\[\]]/g, '\\$&')
@ -17,7 +19,27 @@ function viewportHeight () {
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
}
function populateAsyncUserVideoChannels (authService: AuthService, channel: any[]) {
return new Promise(res => {
authService.userInformationLoaded
.subscribe(
() => {
const user = authService.getUser()
if (!user) return
const videoChannels = user.videoChannels
if (Array.isArray(videoChannels) === false) return
videoChannels.forEach(c => channel.push({ id: c.id, label: c.name }))
return res()
}
)
})
}
export {
viewportHeight,
getParameterByName
getParameterByName,
populateAsyncUserVideoChannels
}

View File

@ -45,7 +45,7 @@ export class VideoEdit {
name: this.name,
tags: this.tags,
nsfw: this.nsfw,
channel: this.channel,
channelId: this.channel,
privacy: this.privacy
}
}

View File

@ -28,12 +28,23 @@
</div>
<div class="col-md-4">
<div class="form-group">
<label>Channel</label>
<div class="peertube-select-disabled-container">
<select formControlName="channelId">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
</div>
<div class="form-group">
<label for="category">Category</label>
<select id="category" formControlName="category">
<option></option>
<option *ngFor="let category of videoCategories" [value]="category.id">{{ category.label }}</option>
</select>
<div class="peertube-select-container">
<select id="category" formControlName="category">
<option></option>
<option *ngFor="let category of videoCategories" [value]="category.id">{{ category.label }}</option>
</select>
</div>
<div *ngIf="formErrors.category" class="form-error">
{{ formErrors.category }}
@ -42,10 +53,12 @@
<div class="form-group">
<label for="licence">Licence</label>
<select id="licence" formControlName="licence">
<option></option>
<option *ngFor="let licence of videoLicences" [value]="licence.id">{{ licence.label }}</option>
</select>
<div class="peertube-select-container">
<select id="licence" formControlName="licence">
<option></option>
<option *ngFor="let licence of videoLicences" [value]="licence.id">{{ licence.label }}</option>
</select>
</div>
<div *ngIf="formErrors.licence" class="form-error">
{{ formErrors.licence }}
@ -54,10 +67,12 @@
<div class="form-group">
<label for="language">Language</label>
<select id="language" formControlName="language">
<option></option>
<option *ngFor="let language of videoLanguages" [value]="language.id">{{ language.label }}</option>
</select>
<div class="peertube-select-container">
<select id="language" formControlName="language">
<option></option>
<option *ngFor="let language of videoLanguages" [value]="language.id">{{ language.label }}</option>
</select>
</div>
<div *ngIf="formErrors.language" class="form-error">
{{ formErrors.language }}
@ -66,11 +81,12 @@
<div class="form-group">
<label for="privacy">Privacy</label>
<select id="privacy" formControlName="privacy">
<option></option>
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
<div class="peertube-select-container">
<select id="privacy" formControlName="privacy">
<option></option>
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
</div>
<div *ngIf="formErrors.privacy" class="form-error">
{{ formErrors.privacy }}

View File

@ -1,6 +1,14 @@
@import '_variables';
@import '_mixins';
.peertube-select-container {
@include peertube-select-container(auto);
}
.peertube-select-disabled-container {
@include peertube-select-disabled-container(auto);
}
.video-edit {
height: 100%;
@ -17,10 +25,6 @@
}
}
select {
@include peertube-select(100%);
}
input, select {
font-size: 15px
}

View File

@ -4,6 +4,7 @@ import { ActivatedRoute, Router } from '@angular/router'
import { NotificationsService } from 'angular2-notifications'
import 'rxjs/add/observable/forkJoin'
import { ServerService } from '../../../core/server'
import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators'
import { ValidatorMessage } from '../../../shared/forms/form-validators/validator-message'
import {
VIDEO_CATEGORY,
@ -27,6 +28,7 @@ export class VideoEditComponent implements OnInit {
@Input() formErrors: { [ id: string ]: string } = {}
@Input() validationMessages: ValidatorMessage = {}
@Input() videoPrivacies = []
@Input() userVideoChannels = []
tags: string[] = []
videoCategories = []
@ -50,6 +52,7 @@ export class VideoEditComponent implements OnInit {
updateForm () {
this.formErrors['name'] = ''
this.formErrors['privacy'] = ''
this.formErrors['channelId'] = ''
this.formErrors['category'] = ''
this.formErrors['licence'] = ''
this.formErrors['language'] = ''
@ -57,6 +60,7 @@ export class VideoEditComponent implements OnInit {
this.validationMessages['name'] = VIDEO_NAME.MESSAGES
this.validationMessages['privacy'] = VIDEO_PRIVACY.MESSAGES
this.validationMessages['channelId'] = VIDEO_CHANNEL.MESSAGES
this.validationMessages['category'] = VIDEO_CATEGORY.MESSAGES
this.validationMessages['licence'] = VIDEO_LICENCE.MESSAGES
this.validationMessages['language'] = VIDEO_LANGUAGE.MESSAGES
@ -64,6 +68,7 @@ export class VideoEditComponent implements OnInit {
this.form.addControl('name', new FormControl('', VIDEO_NAME.VALIDATORS))
this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS))
this.form.addControl('channelId', new FormControl({ value: '', disabled: true }))
this.form.addControl('nsfw', new FormControl(false))
this.form.addControl('category', new FormControl('', VIDEO_CATEGORY.VALIDATORS))
this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))

View File

@ -14,16 +14,22 @@
<input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange()" />
</div>
<div class="form-group">
<select [(ngModel)]="firstStepPrivacyId">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
<div class="form-group form-group-channel">
<label for="first-step-channel">Channel</label>
<div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
</div>
</div>
<div class="form-group">
<select [(ngModel)]="firstStepChannelId">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select>
<label for="first-step-privacy">Privacy</label>
<div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select>
</div>
</div>
</div>
</div>
@ -37,7 +43,7 @@
<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
<my-video-edit
[form]="form" [formErrors]="formErrors"
[validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
[validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
></my-video-edit>

View File

@ -7,17 +7,24 @@
border: 3px solid #EAEAEA;
width: 100%;
height: 440px;
text-align: center;
margin-top: 40px;
display: flex;
justify-content: center;
align-items: center;
.peertube-select-container {
@include peertube-select-container(190px);
}
.upload-video {
display: flex;
flex-direction: column;
align-items: center;
.form-group-channel {
margin-bottom: 20px;
}
.icon.icon-upload {
@include icon(90px);
margin-bottom: 25px;
@ -30,7 +37,8 @@
position: relative;
overflow: hidden;
display: inline-block;
margin-bottom: 70px;
margin-bottom: 45px;
width: 190px;
@include peertube-button;
@include orange-button;
@ -51,13 +59,6 @@
display: block;
}
}
select {
@include peertube-select(auto);
display: inline-block;
font-size: 15px
}
}
}

View File

@ -7,6 +7,7 @@ import { VideoPrivacy } from '../../../../../shared/models/videos'
import { AuthService, ServerService } from '../../core'
import { FormReactive } from '../../shared'
import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
import { populateAsyncUserVideoChannels } from '../../shared/misc/utils'
import { VideoEdit } from '../../shared/video/video-edit.model'
import { VideoService } from '../../shared/video/video.service'
@ -59,6 +60,9 @@ export class VideoAddComponent extends FormReactive implements OnInit {
ngOnInit () {
this.buildForm()
populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
.then(() => this.firstStepChannelId = this.userVideoChannels[0].id)
this.serverService.videoPrivaciesLoaded
.subscribe(
() => {
@ -67,20 +71,6 @@ export class VideoAddComponent extends FormReactive implements OnInit {
// Public by default
this.firstStepPrivacyId = VideoPrivacy.PUBLIC
})
this.authService.userInformationLoaded
.subscribe(
() => {
const user = this.authService.getUser()
if (!user) return
const videoChannels = user.videoChannels
if (Array.isArray(videoChannels) === false) return
this.userVideoChannels = videoChannels.map(v => ({ id: v.id, label: v.name }))
this.firstStepChannelId = this.userVideoChannels[0].id
}
)
}
fileChange () {

View File

@ -7,7 +7,7 @@
<my-video-edit
[form]="form" [formErrors]="formErrors"
[validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
[validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
></my-video-edit>
<div class="submit-container">

View File

@ -5,8 +5,10 @@ import { NotificationsService } from 'angular2-notifications'
import 'rxjs/add/observable/forkJoin'
import { VideoPrivacy } from '../../../../../shared/models/videos'
import { ServerService } from '../../core'
import { AuthService } from '../../core/auth'
import { FormReactive } from '../../shared'
import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
import { populateAsyncUserVideoChannels } from '../../shared/misc/utils'
import { VideoEdit } from '../../shared/video/video-edit.model'
import { VideoService } from '../../shared/video/video.service'
@ -24,6 +26,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
formErrors: { [ id: string ]: string } = {}
validationMessages: ValidatorMessage = {}
videoPrivacies = []
userVideoChannels = []
constructor (
private formBuilder: FormBuilder,
@ -31,7 +34,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
private router: Router,
private notificationsService: NotificationsService,
private serverService: ServerService,
private videoService: VideoService
private videoService: VideoService,
private authService: AuthService
) {
super()
}
@ -44,7 +48,12 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
ngOnInit () {
this.buildForm()
this.videoPrivacies = this.serverService.getVideoPrivacies()
this.serverService.videoPrivaciesLoaded
.subscribe(
() => this.videoPrivacies = this.serverService.getVideoPrivacies()
)
populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
const uuid: string = this.route.snapshot.params['uuid']
this.videoService.getVideo(uuid)

View File

@ -23,10 +23,12 @@
}
@mixin orange-button {
color: #fff;
background-color: $orange-color;
&, &:active, &:focus {
color: #fff;
background-color: $orange-color;
}
&:hover, &:active, &:focus {
&:hover {
color: #fff;
background-color: $orange-hoover-color;
}
@ -39,8 +41,10 @@
}
@mixin grey-button {
background-color: $grey-color;
color: #585858;
&, &:active, &:focus {
background-color: $grey-color;
color: #585858;
}
&:hover, &:active, &:focus, &[disabled], &.disabled {
color: #585858;
@ -88,12 +92,59 @@
}
@mixin peertube-select ($width) {
background-color: #fff;
@mixin peertube-select-container ($width) {
padding: 0;
margin: 0;
border: 1px solid #C6C6C6;
height: $button-height;
width: $width;
border-radius: 3px;
padding-left: 15px;
padding-right: 15px;
overflow: hidden;
background: #fff;
position: relative;
&:after {
top: 50%;
right: calc(0% + 15px);
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border: 5px solid rgba(0, 0, 0, 0);
border-top-color: #000000;
margin-top: -2px;
z-index: 100;
}
select {
padding: 0 12px;
width: calc(100% + 2px);
position: relative;
left: 1px;
border: none;
box-shadow: none;
background: transparent none;
appearance: none;
cursor: pointer;
height: $button-height;
&:focus {
outline: none;
}
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #000;
}
}
}
@mixin peertube-select-disabled-container ($width) {
@include peertube-select-container($width);
background-color: #E5E5E5;
select {
cursor: default;
}
}