Use grid to organise settings in admin, my-account

pull/2538/head
Rigel Kent 2020-03-08 17:33:40 +01:00 committed by Chocobozzz
parent 3b20bdd6dc
commit 482fa503e5
23 changed files with 836 additions and 616 deletions

View File

@ -2,11 +2,11 @@
<div class="sub-menu"> <div class="sub-menu">
<div class="links"> <div class="links">
<a i18n routerLink="instance" routerLinkActive="active" class="title-page">Instance</a> <a i18n routerLink="instance" routerLinkActive="active" class="title-page title-page-about">Instance</a>
<a i18n routerLink="peertube" routerLinkActive="active" class="title-page">PeerTube</a> <a i18n routerLink="peertube" routerLinkActive="active" class="title-page title-page-about">PeerTube</a>
<a i18n routerLink="follows" routerLinkActive="active" class="title-page">Follows</a> <a i18n routerLink="follows" routerLinkActive="active" class="title-page title-page-about">Follows</a>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
<div class="row"> <div class="row">
<div class="sub-menu"> <div class="sub-menu">
<ng-template #linkTemplate let-item="item"> <ng-template #linkTemplate let-item="item">
<a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page">{{ item.label }}</a> <a [routerLink]="item.routerLink" routerLinkActive="active" class="title-page title-page-settings">{{ item.label }}</a>
</ng-template> </ng-template>
<list-overflow [items]="items" [itemTemplate]="linkTemplate"></list-overflow> <list-overflow [items]="items" [itemTemplate]="linkTemplate"></list-overflow>

View File

@ -1,12 +1,19 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
.form-group { $form-base-input-width: 340px;
margin-bottom: 25px;
label {
font-weight: $font-regular;
font-size: 100%;
}
form {
padding-bottom: 1.5rem;
} }
input[type=text] { input[type=text] {
@include peertube-input-text(340px); @include peertube-input-text($form-base-input-width);
display: block; display: block;
} }
@ -20,14 +27,15 @@ input[type=checkbox] {
} }
.peertube-select-container { .peertube-select-container {
@include peertube-select-container(340px); @include peertube-select-container($form-base-input-width);
} }
input[type=submit] { input[type=submit] {
@include peertube-button; @include peertube-button;
@include orange-button; @include orange-button;
margin-top: 20px; display: flex;
margin-left: auto;
& + .form-error { & + .form-error {
display: inline; display: inline;
@ -36,12 +44,7 @@ input[type=submit] {
} }
.inner-form-title { .inner-form-title {
text-transform: uppercase; @include settings-big-title;
color: var(--mainColor);
font-weight: $font-bold;
font-size: 13px;
margin-top: 30px;
margin-bottom: 10px;
} }
textarea { textarea {
@ -63,3 +66,21 @@ textarea {
opacity: .5; opacity: .5;
pointer-events: none; pointer-events: none;
} }
my-markdown-textarea ::ng-deep {
.root {
@media screen and (max-width: 1400px) {
flex-direction: column !important;
}
}
}
.form-group-right {
padding-top: 2px;
}
ngb-tabset:not(.previews) ::ng-deep {
.nav-link {
font-size: 105%;
}
}

View File

@ -13,9 +13,23 @@
font-weight: 600; font-weight: 600;
} }
.ui-button.ui-state-default {
background-color: #f0f0f0;
border: 1px solid #f0f0f0;
}
.ui-button.ui-state-active { .ui-button.ui-state-active {
background-color: var(--mainColor); background-color: var(--mainColor);
border-color: var(--mainColor); border-color: var(--mainColor);
&:hover {
background-color: var(--mainHoverColor);
border-color: var(--mainHoverColor);
}
}
.ui-button:not(.ui-state-active).ui-state-focus {
box-shadow: 0 0 0 .1rem rgba(87, 85, 217, .2);
} }
} }
} }

View File

@ -1,6 +1,11 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
label {
font-weight: $font-regular;
font-size: 100%;
}
input[type=password], input[type=password],
input[type=email] { input[type=email] {
@include peertube-input-text(340px); @include peertube-input-text(340px);
@ -16,7 +21,7 @@ input[type=submit] {
.current-email, .current-email,
.pending-email { .pending-email {
font-size: 16px; font-size: 16px;
margin: 15px 0; margin-bottom: 15px;
.email { .email {
font-weight: $font-semibold; font-weight: $font-semibold;

View File

@ -1,6 +1,11 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
label {
font-weight: $font-regular;
font-size: 100%;
}
input[type=password] { input[type=password] {
@include peertube-input-text(340px); @include peertube-input-text(340px);
display: block; display: block;

View File

@ -1,5 +1,5 @@
<div class="delete-me"> <div class="delete-me">
<p i18n>Once you delete your account, there is no going back. Please be certain.</p> <p i18n>Once you delete your account, there is no going back.</p>
<button (click)="deleteMe()" i18n>Delete your account</button> <button (click)="deleteMe()" i18n>Delete your account</button>
</div> </div>

View File

@ -1,6 +1,11 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
label {
font-weight: $font-regular;
font-size: 100%;
}
input[type=submit] { input[type=submit] {
@include peertube-button; @include peertube-button;
@include orange-button; @include orange-button;

View File

@ -24,5 +24,5 @@
</div> </div>
</div> </div>
<input type="submit" i18n-value value="Update my profile" [disabled]="!form.valid"> <input type="submit" i18n-value value="Save" [disabled]="!form.valid">
</form> </form>

View File

@ -1,6 +1,11 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
label {
font-weight: $font-regular;
font-size: 100%;
}
.form-group:first-child { .form-group:first-child {
margin-bottom: 15px; margin-bottom: 15px;
} }
@ -11,12 +16,6 @@ input[type=text] {
display: block; display: block;
} }
textarea {
@include peertube-textarea(500px, 150px);
display: block;
}
input[type=submit] { input[type=submit] {
@include peertube-button; @include peertube-button;
@include orange-button; @include orange-button;
@ -24,3 +23,8 @@ input[type=submit] {
margin-top: 15px; margin-top: 15px;
} }
textarea {
@include peertube-textarea(500px, 150px);
display: block;
}

View File

@ -1,34 +1,83 @@
<my-actor-avatar-info [actor]="user.account" (avatarChange)="onAvatarChange($event)"></my-actor-avatar-info> <div class="form-row"> <!-- profile grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div class="user-quota"> <div i18n class="account-title">PROFILE</div>
<div>
<span i18n class="user-quota-label">Total video quota:</span>
<ng-container i18n>{{ userVideoQuotaUsed | bytes: 0 }} used</ng-container> / {{ userVideoQuota }}
</div> </div>
<div *ngIf="hasDailyQuota()"> <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<span i18n class="user-quota-label">Daily video quota:</span> <my-actor-avatar-info [actor]="user.account" (avatarChange)="onAvatarChange($event)"></my-actor-avatar-info>
<ng-container>{{ userVideoQuotaUsedDaily | bytes: 0 }} used</ng-container> / {{ userVideoQuotaDaily }}
<div class="user-quota mb-3">
<div>
<label i18n>Total video quota:</label>
<ng-container i18n>{{ userVideoQuotaUsed | bytes: 0 }} used</ng-container> / {{ userVideoQuota }}
</div>
<div *ngIf="hasDailyQuota()">
<label i18n>Daily video quota:</label>
<ng-container>{{ userVideoQuotaUsedDaily | bytes: 0 }} used</ng-container> / {{ userVideoQuotaDaily }}
</div>
</div>
<my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
</div> </div>
</div> </div>
<div i18n class="account-title">Profile</div> <div class="form-row mt-5"> <!-- video settings grid -->
<my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile> <div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">VIDEO SETTINGS</div>
</div>
<div i18n class="account-title">Video settings</div> <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings> <my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings>
</div>
</div>
<div i18n class="account-title">Notifications</div> <div class="form-row mt-5"> <!-- notifications grid -->
<my-account-notification-preferences [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-notification-preferences> <div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">NOTIFICATIONS</div>
</div>
<div i18n class="account-title">Interface</div> <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-interface-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-interface-settings> <my-account-notification-preferences [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-notification-preferences>
</div>
</div>
<div i18n class="account-title">Password</div> <div class="form-row mt-5"> <!-- interface grid -->
<my-account-change-password></my-account-change-password> <div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">INTERFACE</div>
</div>
<div i18n class="account-title">Email</div> <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-change-email></my-account-change-email> <my-account-interface-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-interface-settings>
</div>
</div>
<div i18n class="account-title">Danger zone</div> <div class="form-row mt-5"> <!-- password grid -->
<my-account-danger-zone [user]="user"></my-account-danger-zone> <div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">PASSWORD</div>
</div>
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-change-password></my-account-change-password>
</div>
</div>
<div class="form-row mt-5"> <!-- email grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">EMAIL</div>
</div>
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-change-email></my-account-change-email>
</div>
</div>
<div class="form-row mt-5"> <!-- danger zone grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="account-title">DANGER ZONE</div>
</div>
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<my-account-danger-zone [user]="user"></my-account-danger-zone>
</div>
</div>

View File

@ -5,15 +5,11 @@
font-size: 15px; font-size: 15px;
margin-top: 20px; margin-top: 20px;
.user-quota-label { label {
margin-right: 5px; margin-right: 5px;
font-weight: $font-semibold;
} }
} }
.account-title { .account-title {
@include in-content-small-title; @include settings-big-title;
margin-top: 55px;
margin-bottom: 30px;
} }

View File

@ -1,6 +1,11 @@
@import '_variables'; @import '_variables';
@import '_mixins'; @import '_mixins';
label {
font-weight: $font-regular;
font-size: 100%;
}
input[type=submit] { input[type=submit] {
@include peertube-button; @include peertube-button;
@include orange-button; @include orange-button;

View File

@ -48,6 +48,6 @@ export class ActorAvatarInfoComponent implements OnInit {
} }
get avatarExtensions () { get avatarExtensions () {
return this.serverConfig.avatar.file.extensions.join(',') return this.serverConfig.avatar.file.extensions.join(', ')
} }
} }

View File

@ -22,6 +22,8 @@
align-items: center; align-items: center;
height: 30px !important; height: 30px !important;
padding: 0 15px !important; padding: 0 15px !important;
font-size: 85% !important;
opacity: .7;
} }
.tab-content { .tab-content {

View File

@ -1,12 +1,12 @@
<div class="sub-menu"> <div class="sub-menu">
<ng-container *ngFor="let menuEntry of menuEntries"> <ng-container *ngFor="let menuEntry of menuEntries">
<a *ngIf="menuEntry.routerLink" [routerLink]="menuEntry.routerLink" routerLinkActive="active" class="title-page">{{ menuEntry.label }}</a> <a *ngIf="menuEntry.routerLink" [routerLink]="menuEntry.routerLink" routerLinkActive="active" class="title-page title-page-settings">{{ menuEntry.label }}</a>
<div *ngIf="!menuEntry.routerLink" ngbDropdown [container]="container" class="parent-entry" #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)"> <div *ngIf="!menuEntry.routerLink" ngbDropdown [container]="container" class="parent-entry" #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)">
<span <span
(mouseenter)="openDropdownOnHover(dropdown)" [ngClass]="{ active: !!suffixLabels[menuEntry.label] }" ngbDropdownAnchor (mouseenter)="openDropdownOnHover(dropdown)" [ngClass]="{ active: !!suffixLabels[menuEntry.label] }" ngbDropdownAnchor
(click)="dropdownAnchorClicked(dropdown)" role="button" class="title-page" (click)="dropdownAnchorClicked(dropdown)" role="button" class="title-page title-page-settings"
> >
<ng-container i18n>{{ menuEntry.label }}</ng-container> <ng-container i18n>{{ menuEntry.label }}</ng-container>
<ng-container *ngIf="!!suffixLabels[menuEntry.label]"> - {{ suffixLabels[menuEntry.label] }}</ng-container> <ng-container *ngIf="!!suffixLabels[menuEntry.label]"> - {{ suffixLabels[menuEntry.label] }}</ng-container>

View File

@ -174,6 +174,16 @@ label {
} }
} }
.title-page-about,
.title-page-settings {
font-size: 115%;
font-weight: $font-regular;
&.active {
font-weight: $font-semibold;
}
}
.admin-sub-header { .admin-sub-header {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -175,10 +175,10 @@ ngb-tabset {
.nav-tabs .nav-link { .nav-tabs .nav-link {
&:not(.active) { &:not(.active) {
opacity: .6;
border-bottom: 3px solid transparent; border-bottom: 3px solid transparent;
} }
&.active { &.active {
font-weight: $font-semibold;
background-color: var(--mainBackgroundColor) !important; background-color: var(--mainBackgroundColor) !important;
border: none; border: none;
border-bottom: 2px solid var(--mainColor); border-bottom: 2px solid var(--mainColor);

View File

@ -463,6 +463,14 @@
font-size: 13px; font-size: 13px;
} }
@mixin settings-big-title {
text-transform: uppercase;
color: var(--mainColor);
font-weight: $font-bold;
font-size: 110%;
margin-bottom: 10px;
}
@mixin actor-owner { @mixin actor-owner {
@include disable-default-a-behaviour; @include disable-default-a-behaviour;

View File

@ -249,7 +249,7 @@ auto_blacklist:
instance: instance:
name: 'PeerTube' name: 'PeerTube'
short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.' short_description: 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
description: 'Welcome to this PeerTube instance!' # Support markdown description: 'Welcome to this PeerTube instance!' # Support markdown
terms: 'No terms for now.' # Support markdown terms: 'No terms for now.' # Support markdown
code_of_conduct: '' # Supports markdown code_of_conduct: '' # Supports markdown

View File

@ -27,8 +27,7 @@ const expect = chai.expect
function checkInitialConfig (server: ServerInfo, data: CustomConfig) { function checkInitialConfig (server: ServerInfo, data: CustomConfig) {
expect(data.instance.name).to.equal('PeerTube') expect(data.instance.name).to.equal('PeerTube')
expect(data.instance.shortDescription).to.equal( expect(data.instance.shortDescription).to.equal(
'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser ' + 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
'with WebTorrent and Angular.'
) )
expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')

View File

@ -112,8 +112,7 @@ describe('Test a client controllers', function () {
it('Should have valid index html tags (title, description...)', async function () { it('Should have valid index html tags (title, description...)', async function () {
const res = await makeHTMLRequest(server.url, '/videos/trending') const res = await makeHTMLRequest(server.url, '/videos/trending')
const description = 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser ' + const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
'with WebTorrent and Angular.'
checkIndexTags(res.text, 'PeerTube', description, '') checkIndexTags(res.text, 'PeerTube', description, '')
}) })