mirror of https://github.com/Chocobozzz/PeerTube
Fix channel sync edit/list
* Edit -> prefer to use reactive forms for required inputs * List -> use chip class to fix the channel displaypull/6648/head
parent
ae31ff79ac
commit
639feb2306
|
@ -54,21 +54,19 @@
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<div class="actor">
|
<a [routerLink]="[ '/c', videoChannelSync.channel.name ]" i18n-title title="Channel page">
|
||||||
<my-actor-avatar
|
<div class="chip two-lines">
|
||||||
class="channel"
|
<my-actor-avatar
|
||||||
[actor]="videoChannelSync.channel" actorType="channel"
|
[actor]="videoChannelSync.channel" actorType="channel"
|
||||||
[internalHref]="[ '/c', videoChannelSync.channel.name ]"
|
[internalHref]="[ '/c', videoChannelSync.channel.name ]" size="32"
|
||||||
size="25"
|
></my-actor-avatar>
|
||||||
></my-actor-avatar>
|
|
||||||
|
|
||||||
<div class="actor-info">
|
<div>
|
||||||
<a [routerLink]="[ '/c', videoChannelSync.channel.name ]" class="actor-names" i18n-title title="Channel page">
|
<span class="fw-semibold">{{ videoChannelSync.channel.displayName }}</span>
|
||||||
<div class="actor-display-name">{{ videoChannelSync.channel.displayName }}</div>
|
<span class="muted">{{ videoChannelSync.channel.name }}</span>
|
||||||
<div class="actor-name">{{ videoChannelSync.channel.name }}</div>
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
@use '_variables' as *;
|
|
||||||
@use '_mixins' as *;
|
|
||||||
@use '_actor' as *;
|
|
||||||
|
|
||||||
.actor {
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
border: 0;
|
|
||||||
|
|
||||||
@include actor-row($min-height: auto, $separator: true);
|
|
||||||
}
|
|
|
@ -16,7 +16,6 @@ import { ActionDropdownComponent, DropdownAction } from '../../shared/shared-mai
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './my-video-channel-syncs.component.html',
|
templateUrl: './my-video-channel-syncs.component.html',
|
||||||
styleUrls: [ './my-video-channel-syncs.component.scss' ],
|
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
NgIf,
|
NgIf,
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="videoChannel">Video Channel</label>
|
<label i18n for="videoChannel">Video channel</label>
|
||||||
<my-select-channel required [items]="userVideoChannels" formControlName="videoChannel"></my-select-channel>
|
<my-select-channel labelForId="videoChannel" [items]="userVideoChannels" formControlName="videoChannel"></my-select-channel>
|
||||||
|
|
||||||
<div *ngIf="formErrors['videoChannel']" class="form-error" role="alert">
|
<div *ngIf="formErrors['videoChannel']" class="form-error" role="alert">
|
||||||
{{ formErrors['videoChannel'] }}
|
{{ formErrors['videoChannel'] }}
|
||||||
|
@ -42,12 +42,12 @@
|
||||||
<label for="existingVideoStrategy" i18n>Options for existing videos on remote channel:</label>
|
<label for="existingVideoStrategy" i18n>Options for existing videos on remote channel:</label>
|
||||||
|
|
||||||
<div class="peertube-radio-container">
|
<div class="peertube-radio-container">
|
||||||
<input type="radio" name="existingVideoStrategy" id="import" value="import" formControlName="existingVideoStrategy" required />
|
<input type="radio" name="existingVideoStrategy" id="import" value="import" formControlName="existingVideoStrategy" />
|
||||||
<label for="import" i18n>Import all and watch for new publications</label>
|
<label for="import" i18n>Import all and watch for new publications</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="peertube-radio-container">
|
<div class="peertube-radio-container">
|
||||||
<input type="radio" name="existingVideoStrategy" id="doNothing" value="nothing" formControlName="existingVideoStrategy" required />
|
<input type="radio" name="existingVideoStrategy" id="doNothing" value="nothing" formControlName="existingVideoStrategy" />
|
||||||
<label for="doNothing" i18n>Only watch for new publications</label>
|
<label for="doNothing" i18n>Only watch for new publications</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { VideoChannelSyncCreate } from '@peertube/peertube-models'
|
||||||
import { mergeMap } from 'rxjs'
|
import { mergeMap } from 'rxjs'
|
||||||
import { SelectChannelItem } from 'src/types'
|
import { SelectChannelItem } from 'src/types'
|
||||||
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
|
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
|
||||||
|
import { REQUIRED_VALIDATOR } from '@app/shared/form-validators/common-validators'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-channel-sync-edit',
|
selector: 'my-video-channel-sync-edit',
|
||||||
|
@ -41,8 +42,8 @@ export class VideoChannelSyncEditComponent extends FormReactive implements OnIni
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.buildForm({
|
this.buildForm({
|
||||||
externalChannelUrl: VIDEO_CHANNEL_EXTERNAL_URL_VALIDATOR,
|
externalChannelUrl: VIDEO_CHANNEL_EXTERNAL_URL_VALIDATOR,
|
||||||
videoChannel: null,
|
videoChannel: REQUIRED_VALIDATOR,
|
||||||
existingVideoStrategy: null
|
existingVideoStrategy: REQUIRED_VALIDATOR
|
||||||
})
|
})
|
||||||
|
|
||||||
listUserChannelsForSelect(this.authService)
|
listUserChannelsForSelect(this.authService)
|
||||||
|
|
|
@ -69,11 +69,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="videoChannelIdl" i18n>Channel</label>
|
<label for="videoChannelId" i18n>Channel</label>
|
||||||
|
|
||||||
<my-select-channel
|
<my-select-channel labelForId="videoChannelId" [items]="userVideoChannels" formControlName="videoChannelId"></my-select-channel>
|
||||||
labelForId="videoChannelId" [items]="userVideoChannels" formControlName="videoChannelId"
|
|
||||||
></my-select-channel>
|
|
||||||
|
|
||||||
<div *ngIf="formErrors['videoChannelId']" class="form-error" role="alert">{{ formErrors['videoChannelId'] }}</div>
|
<div *ngIf="formErrors['videoChannelId']" class="form-error" role="alert">{{ formErrors['videoChannelId'] }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="first-step-channel">Channel</label>
|
<label i18n for="first-step-channel">Channel</label>
|
||||||
<my-select-channel
|
<my-select-channel labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"></my-select-channel>
|
||||||
labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"
|
|
||||||
></my-select-channel>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -28,9 +28,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="first-step-channel">Channel</label>
|
<label i18n for="first-step-channel">Channel</label>
|
||||||
<my-select-channel
|
<my-select-channel labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"></my-select-channel>
|
||||||
labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"
|
|
||||||
></my-select-channel>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -24,9 +24,7 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="first-step-channel">Channel</label>
|
<label i18n for="first-step-channel">Channel</label>
|
||||||
<my-select-channel
|
<my-select-channel labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"></my-select-channel>
|
||||||
labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"
|
|
||||||
></my-select-channel>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -17,9 +17,7 @@
|
||||||
|
|
||||||
<div class="form-group form-group-channel">
|
<div class="form-group form-group-channel">
|
||||||
<label i18n for="first-step-channel">Channel</label>
|
<label i18n for="first-step-channel">Channel</label>
|
||||||
<my-select-channel
|
<my-select-channel labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"></my-select-channel>
|
||||||
labelForId="first-step-channel" [items]="userVideoChannels" [(ngModel)]="firstStepChannelId"
|
|
||||||
></my-select-channel>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Validators } from '@angular/forms'
|
||||||
|
import { BuildFormValidator } from './form-validator.model'
|
||||||
|
|
||||||
|
export const REQUIRED_VALIDATOR: BuildFormValidator = {
|
||||||
|
VALIDATORS: [ Validators.required ],
|
||||||
|
MESSAGES: {
|
||||||
|
required: $localize`This field is required.`
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
[bindValue]="bindValue"
|
[bindValue]="bindValue"
|
||||||
[clearable]="clearable"
|
[clearable]="clearable"
|
||||||
[searchable]="searchable"
|
[searchable]="searchable"
|
||||||
|
[labelForId]="labelForId"
|
||||||
>
|
>
|
||||||
<ng-option *ngFor="let channel of channels" [value]="channel.id">
|
<ng-option *ngFor="let channel of channels" [value]="channel.id">
|
||||||
<img alt="" class="avatar me-1" [src]="channel.avatarPath" />
|
<img alt="" class="avatar me-1" [src]="channel.avatarPath" />
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.mode
|
||||||
imports: [ NgSelectModule, FormsModule, NgFor ]
|
imports: [ NgSelectModule, FormsModule, NgFor ]
|
||||||
})
|
})
|
||||||
export class SelectChannelComponent implements ControlValueAccessor, OnChanges {
|
export class SelectChannelComponent implements ControlValueAccessor, OnChanges {
|
||||||
|
@Input({ required: true }) labelForId: string
|
||||||
@Input() items: SelectChannelItem[] = []
|
@Input() items: SelectChannelItem[] = []
|
||||||
|
|
||||||
channels: SelectChannelItem[] = []
|
channels: SelectChannelItem[] = []
|
||||||
|
|
|
@ -99,7 +99,43 @@
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
.chip {
|
.chip {
|
||||||
@include chip;
|
--avatarSize: 1.2rem;
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
color: pvar(--mainForegroundColor);
|
||||||
|
height: var(--avatarSize);
|
||||||
|
max-width: 320px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-decoration: none;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
my-actor-avatar {
|
||||||
|
border-radius: 5rem;
|
||||||
|
width: var(--avatarSize);
|
||||||
|
height: var(--avatarSize);
|
||||||
|
|
||||||
|
@include margin-right(0.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.two-lines {
|
||||||
|
--avatarSize: 2rem;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1rem;
|
||||||
|
|
||||||
|
my-actor-avatar {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -620,45 +620,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin chip {
|
|
||||||
--avatar-size: 1.2rem;
|
|
||||||
|
|
||||||
display: inline-flex;
|
|
||||||
color: pvar(--mainForegroundColor);
|
|
||||||
height: var(--avatar-size);
|
|
||||||
max-width: 320px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-decoration: none;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
vertical-align: middle;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
my-actor-avatar {
|
|
||||||
border-radius: 5rem;
|
|
||||||
width: var(--avatar-size);
|
|
||||||
height: var(--avatar-size);
|
|
||||||
|
|
||||||
@include margin-right(.2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.two-lines {
|
|
||||||
--avatar-size: 2rem;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1rem;
|
|
||||||
|
|
||||||
my-actor-avatar {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// applies ratio (default to 16:9) to a child element (using $selector) only using
|
// applies ratio (default to 16:9) to a child element (using $selector) only using
|
||||||
// an immediate's parent size. This allows to set a ratio without explicit
|
// an immediate's parent size. This allows to set a ratio without explicit
|
||||||
// dimensions, as width/height cannot be computed from each other.
|
// dimensions, as width/height cannot be computed from each other.
|
||||||
|
|
Loading…
Reference in New Issue