diff options
author | Chocobozzz <me@florianbigard.com> | 2020-06-23 14:10:17 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-06-23 16:00:49 +0200 |
commit | 67ed6552b831df66713bac9e672738796128d33f (patch) | |
tree | 59c97d41e0b49d75a90aa3de987968ab9b1ff447 /client/src/app/shared/shared-main/buttons | |
parent | 0c4bacbff53bc732f5a2677d62a6ead7752e2405 (diff) | |
download | PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.gz PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.zst PeerTube-67ed6552b831df66713bac9e672738796128d33f.zip |
Reorganize client shared modules
Diffstat (limited to 'client/src/app/shared/shared-main/buttons')
11 files changed, 299 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.html b/client/src/app/shared/shared-main/buttons/action-dropdown.component.html new file mode 100644 index 000000000..12933d4ca --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.html | |||
@@ -0,0 +1,55 @@ | |||
1 | <div class="dropdown-root" ngbDropdown [placement]="placement" [container]="container" *ngIf="areActionsDisplayed(actions, entry)"> | ||
2 | <button | ||
3 | class="action-button" [ngClass]="{ small: buttonSize === 'small', grey: theme === 'grey', orange: theme === 'orange', 'button-styled': buttonStyled }" | ||
4 | ngbDropdownToggle role="button" | ||
5 | > | ||
6 | <my-global-icon *ngIf="!label && buttonDirection === 'horizontal'" class="more-icon" iconName="more-horizontal"></my-global-icon> | ||
7 | <my-global-icon *ngIf="!label && buttonDirection === 'vertical'" class="more-icon" iconName="more-vertical"></my-global-icon> | ||
8 | |||
9 | <span *ngIf="label" class="dropdown-toggle">{{ label }}</span> | ||
10 | </button> | ||
11 | |||
12 | <div ngbDropdownMenu class="dropdown-menu"> | ||
13 | <ng-container *ngFor="let actions of getActions()"> | ||
14 | |||
15 | <ng-container *ngFor="let action of actions"> | ||
16 | <ng-container *ngIf="action.isDisplayed === undefined || action.isDisplayed(entry) === true"> | ||
17 | |||
18 | <ng-template #templateActionLabel let-action> | ||
19 | <my-global-icon *ngIf="action.iconName" [iconName]="action.iconName" [ngClass]="'icon-' + action.iconName" aria-hidden="true"></my-global-icon> | ||
20 | |||
21 | <div class="d-flex flex-column"> | ||
22 | <span i18n>{{ action.label }}</span> | ||
23 | <small class="text-muted" *ngIf="action.description">{{ action.description }}</small> | ||
24 | </div> | ||
25 | </ng-template> | ||
26 | |||
27 | <a | ||
28 | *ngIf="action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }" | ||
29 | class="dropdown-item" [routerLink]="action.linkBuilder(entry)" [title]="action.title || ''" | ||
30 | > | ||
31 | <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container> | ||
32 | </a> | ||
33 | |||
34 | <span | ||
35 | *ngIf="!action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }" | ||
36 | class="custom-action dropdown-item" tabindex="0" role="button" [title]="action.title || ''" (click)="action.handler(entry)" (keyup.enter)="action.handler(entry)" | ||
37 | > | ||
38 | <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container> | ||
39 | </span> | ||
40 | |||
41 | <h6 | ||
42 | *ngIf="!action.linkBuilder && action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }" | ||
43 | class="dropdown-header" tabindex="0" role="button" [title]="action.title || ''" (click)="action.handler(entry)" (keyup.enter)="action.handler(entry)" | ||
44 | > | ||
45 | <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container> | ||
46 | </h6> | ||
47 | |||
48 | </ng-container> | ||
49 | </ng-container> | ||
50 | |||
51 | <div *ngIf="areActionsDisplayed(actions, entry)" class="dropdown-divider"></div> | ||
52 | |||
53 | </ng-container> | ||
54 | </div> | ||
55 | </div> | ||
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss b/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss new file mode 100644 index 000000000..724a04efc --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss | |||
@@ -0,0 +1,72 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .dropdown-divider:last-child { | ||
5 | display: none; | ||
6 | } | ||
7 | |||
8 | .action-button { | ||
9 | @include peertube-button; | ||
10 | |||
11 | &.button-styled { | ||
12 | |||
13 | &.grey { | ||
14 | @include grey-button; | ||
15 | } | ||
16 | |||
17 | &.orange { | ||
18 | @include orange-button; | ||
19 | } | ||
20 | |||
21 | &:hover, &:active, &:focus { | ||
22 | background-color: $grey-background-color; | ||
23 | } | ||
24 | } | ||
25 | |||
26 | display: inline-block; | ||
27 | padding: 0 10px; | ||
28 | |||
29 | &::after { | ||
30 | display: none; | ||
31 | } | ||
32 | |||
33 | .more-icon { | ||
34 | width: 21px; | ||
35 | |||
36 | ::ng-deep { | ||
37 | @include apply-svg-color(pvar(--actionButtonColor)); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | &.small { | ||
42 | font-size: 14px; | ||
43 | height: 20px; | ||
44 | line-height: 20px; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | .dropdown-toggle::after { | ||
49 | position: relative; | ||
50 | top: 1px; | ||
51 | } | ||
52 | |||
53 | .dropdown-menu { | ||
54 | .dropdown-header { | ||
55 | padding: 0.2rem 1rem; | ||
56 | } | ||
57 | |||
58 | .dropdown-item { | ||
59 | display: flex; | ||
60 | cursor: pointer; | ||
61 | color: #000 !important; | ||
62 | |||
63 | &.with-icon { | ||
64 | @include dropdown-with-icon-item; | ||
65 | } | ||
66 | |||
67 | a, span { | ||
68 | display: block; | ||
69 | width: 100%; | ||
70 | } | ||
71 | } | ||
72 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts b/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts new file mode 100644 index 000000000..36d7d6229 --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts | |||
@@ -0,0 +1,52 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { GlobalIconName } from '@app/shared/shared-icons' | ||
3 | |||
4 | export type DropdownAction<T> = { | ||
5 | label?: string | ||
6 | iconName?: GlobalIconName | ||
7 | description?: string | ||
8 | title?: string | ||
9 | handler?: (a: T) => any | ||
10 | linkBuilder?: (a: T) => (string | number)[] | ||
11 | isDisplayed?: (a: T) => boolean | ||
12 | isHeader?: boolean | ||
13 | } | ||
14 | |||
15 | export type DropdownButtonSize = 'normal' | 'small' | ||
16 | export type DropdownTheme = 'orange' | 'grey' | ||
17 | export type DropdownDirection = 'horizontal' | 'vertical' | ||
18 | |||
19 | @Component({ | ||
20 | selector: 'my-action-dropdown', | ||
21 | styleUrls: [ './action-dropdown.component.scss' ], | ||
22 | templateUrl: './action-dropdown.component.html' | ||
23 | }) | ||
24 | |||
25 | export class ActionDropdownComponent<T> { | ||
26 | @Input() actions: DropdownAction<T>[] | DropdownAction<T>[][] = [] | ||
27 | @Input() entry: T | ||
28 | |||
29 | @Input() placement = 'bottom-left auto' | ||
30 | @Input() container: null | 'body' | ||
31 | |||
32 | @Input() buttonSize: DropdownButtonSize = 'normal' | ||
33 | @Input() buttonDirection: DropdownDirection = 'horizontal' | ||
34 | @Input() buttonStyled = true | ||
35 | |||
36 | @Input() label: string | ||
37 | @Input() theme: DropdownTheme = 'grey' | ||
38 | |||
39 | getActions (): DropdownAction<T>[][] { | ||
40 | if (this.actions.length !== 0 && Array.isArray(this.actions[0])) return this.actions as DropdownAction<T>[][] | ||
41 | |||
42 | return [ this.actions as DropdownAction<T>[] ] | ||
43 | } | ||
44 | |||
45 | areActionsDisplayed (actions: Array<DropdownAction<T> | DropdownAction<T>[]>, entry: T): boolean { | ||
46 | return actions.some(a => { | ||
47 | if (Array.isArray(a)) return this.areActionsDisplayed(a, entry) | ||
48 | |||
49 | return a.isDisplayed === undefined || a.isDisplayed(entry) | ||
50 | }) | ||
51 | } | ||
52 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/button.component.html b/client/src/app/shared/shared-main/buttons/button.component.html new file mode 100644 index 000000000..d2b0eb81a --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/button.component.html | |||
@@ -0,0 +1,6 @@ | |||
1 | <span class="action-button" [ngClass]="className" [title]="getTitle()"> | ||
2 | <my-global-icon *ngIf="!loading" [iconName]="icon"></my-global-icon> | ||
3 | <my-small-loader [loading]="loading"></my-small-loader> | ||
4 | |||
5 | <span class="button-label">{{ label }}</span> | ||
6 | </span> | ||
diff --git a/client/src/app/shared/shared-main/buttons/button.component.scss b/client/src/app/shared/shared-main/buttons/button.component.scss new file mode 100644 index 000000000..3ccfefd7e --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/button.component.scss | |||
@@ -0,0 +1,46 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | my-small-loader ::ng-deep .root { | ||
5 | display: inline-block; | ||
6 | margin: 0 3px 0 0; | ||
7 | width: 20px; | ||
8 | } | ||
9 | |||
10 | .action-button { | ||
11 | @include peertube-button-link; | ||
12 | @include button-with-icon(21px, 0, -2px); | ||
13 | } | ||
14 | |||
15 | .orange-button { | ||
16 | @include peertube-button; | ||
17 | @include orange-button; | ||
18 | } | ||
19 | |||
20 | .orange-button-link { | ||
21 | @include peertube-button-link; | ||
22 | @include orange-button; | ||
23 | } | ||
24 | |||
25 | .grey-button { | ||
26 | @include peertube-button; | ||
27 | @include grey-button; | ||
28 | } | ||
29 | |||
30 | .grey-button-link { | ||
31 | @include peertube-button-link; | ||
32 | @include grey-button; | ||
33 | } | ||
34 | |||
35 | // In a table, try to minimize the space taken by this button | ||
36 | @media screen and (max-width: 1400px) { | ||
37 | :host-context(td) { | ||
38 | .action-button { | ||
39 | padding: 0 13px; | ||
40 | } | ||
41 | |||
42 | .button-label { | ||
43 | display: none; | ||
44 | } | ||
45 | } | ||
46 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/button.component.ts b/client/src/app/shared/shared-main/buttons/button.component.ts new file mode 100644 index 000000000..e23b90945 --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/button.component.ts | |||
@@ -0,0 +1,20 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { GlobalIconName } from '@app/shared/shared-icons' | ||
3 | |||
4 | @Component({ | ||
5 | selector: 'my-button', | ||
6 | styleUrls: ['./button.component.scss'], | ||
7 | templateUrl: './button.component.html' | ||
8 | }) | ||
9 | |||
10 | export class ButtonComponent { | ||
11 | @Input() label = '' | ||
12 | @Input() className = 'grey-button' | ||
13 | @Input() icon: GlobalIconName = undefined | ||
14 | @Input() title: string = undefined | ||
15 | @Input() loading = false | ||
16 | |||
17 | getTitle () { | ||
18 | return this.title || this.label | ||
19 | } | ||
20 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.html b/client/src/app/shared/shared-main/buttons/delete-button.component.html new file mode 100644 index 000000000..398b6db1e --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/delete-button.component.html | |||
@@ -0,0 +1,6 @@ | |||
1 | <span class="action-button action-button-delete grey-button" [title]="title" role="button"> | ||
2 | <my-global-icon iconName="delete" aria-hidden="true"></my-global-icon> | ||
3 | |||
4 | <span class="button-label" *ngIf="label">{{ label }}</span> | ||
5 | <span class="button-label" i18n *ngIf="!label">Delete</span> | ||
6 | </span> | ||
diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.ts b/client/src/app/shared/shared-main/buttons/delete-button.component.ts new file mode 100644 index 000000000..39e31900f --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/delete-button.component.ts | |||
@@ -0,0 +1,20 @@ | |||
1 | import { Component, Input, OnInit } from '@angular/core' | ||
2 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
3 | |||
4 | @Component({ | ||
5 | selector: 'my-delete-button', | ||
6 | styleUrls: [ './button.component.scss' ], | ||
7 | templateUrl: './delete-button.component.html' | ||
8 | }) | ||
9 | |||
10 | export class DeleteButtonComponent implements OnInit { | ||
11 | @Input() label: string | ||
12 | |||
13 | title: string | ||
14 | |||
15 | constructor (private i18n: I18n) { } | ||
16 | |||
17 | ngOnInit () { | ||
18 | this.title = this.label || this.i18n('Delete') | ||
19 | } | ||
20 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.html b/client/src/app/shared/shared-main/buttons/edit-button.component.html new file mode 100644 index 000000000..b852bb38a --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/edit-button.component.html | |||
@@ -0,0 +1,6 @@ | |||
1 | <a class="action-button action-button-edit grey-button" [routerLink]="routerLink" i18n-title title="Edit"> | ||
2 | <my-global-icon iconName="edit" aria-hidden="true"></my-global-icon> | ||
3 | |||
4 | <span class="button-label" *ngIf="label">{{ label }}</span> | ||
5 | <span i18n class="button-label" *ngIf="!label">Edit</span> | ||
6 | </a> | ||
diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.ts b/client/src/app/shared/shared-main/buttons/edit-button.component.ts new file mode 100644 index 000000000..9cfe1a3bb --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/edit-button.component.ts | |||
@@ -0,0 +1,12 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | |||
3 | @Component({ | ||
4 | selector: 'my-edit-button', | ||
5 | styleUrls: [ './button.component.scss' ], | ||
6 | templateUrl: './edit-button.component.html' | ||
7 | }) | ||
8 | |||
9 | export class EditButtonComponent { | ||
10 | @Input() label: string | ||
11 | @Input() routerLink: string[] | string = [] | ||
12 | } | ||
diff --git a/client/src/app/shared/shared-main/buttons/index.ts b/client/src/app/shared/shared-main/buttons/index.ts new file mode 100644 index 000000000..775a47a39 --- /dev/null +++ b/client/src/app/shared/shared-main/buttons/index.ts | |||
@@ -0,0 +1,4 @@ | |||
1 | export * from './action-dropdown.component' | ||
2 | export * from './button.component' | ||
3 | export * from './delete-button.component' | ||
4 | export * from './edit-button.component' | ||