refactor(web): settings switches are @pi/ui's slide toggle
Visibility, the public's proposals, the definition of done and the link for clients each had a hand-made switch; they use pi-slide-toggle now, like the bell's, with their state written beside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,12 @@ import {
|
||||
untracked,
|
||||
} from '@angular/core';
|
||||
import { NgTemplateOutlet } from '@angular/common';
|
||||
import { PiCheckboxComponent, PiIconComponent, PiNoteComponent } from '@pi/ui';
|
||||
import {
|
||||
PiCheckboxComponent,
|
||||
PiIconComponent,
|
||||
PiNoteComponent,
|
||||
PiSlideToggleComponent,
|
||||
} from '@pi/ui';
|
||||
import { GitIntegrationComponent } from '../ui/git-integration';
|
||||
import { WebhooksComponent } from '../ui/webhooks';
|
||||
import { TransferComponent } from '../ui/transfer';
|
||||
@@ -151,6 +156,7 @@ function idFrom(name: string): string {
|
||||
NgTemplateOutlet,
|
||||
PiIconComponent,
|
||||
PiNoteComponent,
|
||||
PiSlideToggleComponent,
|
||||
],
|
||||
template: `
|
||||
<div class="ts-settings-layout">
|
||||
@@ -209,17 +215,15 @@ function idFrom(name: string): string {
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<label class="ts-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
<div class="ts-toggle">
|
||||
<pi-slide-toggle
|
||||
label="Proyecto público"
|
||||
[checked]="project.isPublic"
|
||||
[disabled]="!facade.canManage()"
|
||||
(change)="facade.setPublic($any($event.target).checked)"
|
||||
(checkedChange)="facade.setPublic($event)"
|
||||
/>
|
||||
<span class="ts-switch__track" aria-hidden="true"></span>
|
||||
<span>{{ project.isPublic ? 'Público' : 'Privado' }}</span>
|
||||
</label>
|
||||
<span aria-hidden="true">{{ project.isPublic ? 'Público' : 'Privado' }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
@@ -245,19 +249,15 @@ function idFrom(name: string): string {
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<label class="ts-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
<div class="ts-toggle">
|
||||
<pi-slide-toggle
|
||||
label="Propuestas del público abiertas"
|
||||
[checked]="project.isPublic && project.acceptsProposals"
|
||||
[disabled]="!facade.canManage() || !project.isPublic"
|
||||
(change)="facade.setAcceptsProposals($any($event.target).checked)"
|
||||
(checkedChange)="facade.setAcceptsProposals($event)"
|
||||
/>
|
||||
<span class="ts-switch__track" aria-hidden="true"></span>
|
||||
<span>{{
|
||||
project.isPublic && project.acceptsProposals ? 'Abierto' : 'Cerrado'
|
||||
}}</span>
|
||||
</label>
|
||||
<span aria-hidden="true">{{ project.isPublic && project.acceptsProposals ? 'Abierto' : 'Cerrado' }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@if (facade.canManage()) {
|
||||
@@ -464,20 +464,14 @@ function idFrom(name: string): string {
|
||||
medias. El propietario y los admins sí pueden cerrarlo.
|
||||
</p>
|
||||
</div>
|
||||
<label class="ts-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
[checked]="!!d.checklistBeforeDone"
|
||||
(change)="
|
||||
setChecklistBeforeDone($any($event.target).checked)
|
||||
"
|
||||
/>
|
||||
<span class="ts-switch__track" aria-hidden="true"></span>
|
||||
<span>{{
|
||||
d.checklistBeforeDone ? 'Activada' : 'Desactivada'
|
||||
}}</span>
|
||||
</label>
|
||||
<div class="ts-toggle">
|
||||
<pi-slide-toggle
|
||||
label="Definición de «Hecho» activada"
|
||||
[checked]="!!d.checklistBeforeDone"
|
||||
(checkedChange)="setChecklistBeforeDone($event)"
|
||||
/>
|
||||
<span aria-hidden="true">{{ d.checklistBeforeDone ? 'Activada' : 'Desactivada' }}</span>
|
||||
</div>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
@@ -1108,59 +1102,12 @@ function idFrom(name: string): string {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
}
|
||||
.ts-switch {
|
||||
.ts-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
input:focus-visible + .ts-switch__track {
|
||||
outline: 2px solid var(--ts-brand);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
input:disabled ~ * {
|
||||
opacity: 0.6;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.ts-switch__track {
|
||||
position: relative;
|
||||
width: 2.5rem;
|
||||
height: 1.375rem;
|
||||
border-radius: 999px;
|
||||
background: var(--ts-line-strong);
|
||||
transition: background-color 0.15s ease;
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
border-radius: 50%;
|
||||
background: var(--ts-surface);
|
||||
box-shadow: var(--ts-shadow);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
}
|
||||
.ts-switch input:checked + .ts-switch__track {
|
||||
background: var(--ts-brand);
|
||||
&::after {
|
||||
transform: translateX(1.125rem);
|
||||
}
|
||||
}
|
||||
.ts-danger {
|
||||
border: 1px solid color-mix(in srgb, var(--ts-c-red) 45%, transparent);
|
||||
h3 {
|
||||
color: var(--ts-c-red);
|
||||
}
|
||||
}
|
||||
.ts-danger__confirm {
|
||||
display: flex;
|
||||
@@ -1453,12 +1400,6 @@ function idFrom(name: string): string {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
input[type='checkbox'] {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
accent-color: var(--ts-brand);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ts-type-icon {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
input,
|
||||
untracked,
|
||||
} from '@angular/core';
|
||||
import { PiCheckboxComponent } from '@pi/ui';
|
||||
import { PiCheckboxComponent, PiSlideToggleComponent } from '@pi/ui';
|
||||
import { ToastService } from '@task-stream/web/shared/ui';
|
||||
import {
|
||||
provideSharingFacade,
|
||||
@@ -37,7 +37,7 @@ const DEFAULT_BLOCKS: SharedBlock[] = ['flow', 'sprint', 'releases'];
|
||||
@Component({
|
||||
selector: 'ts-client-share',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [PiCheckboxComponent],
|
||||
imports: [PiCheckboxComponent, PiSlideToggleComponent],
|
||||
providers: [provideSharingFacade()],
|
||||
host: { class: 'ts-panel', role: 'region', 'aria-labelledby': 'share-title' },
|
||||
template: `
|
||||
@@ -49,17 +49,17 @@ const DEFAULT_BLOCKS: SharedBlock[] = ['flow', 'sprint', 'releases'];
|
||||
enseña personas ni tickets sueltos (salvo las épicas).
|
||||
</p>
|
||||
</div>
|
||||
<label class="ts-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
<div class="ts-toggle">
|
||||
<pi-slide-toggle
|
||||
label="Panel para clientes compartido"
|
||||
[checked]="!!sharing.share()"
|
||||
[disabled]="!sharing.loaded() || sharing.busy()"
|
||||
(change)="toggle($any($event.target).checked)"
|
||||
(checkedChange)="toggle($event)"
|
||||
/>
|
||||
<span class="ts-switch__track" aria-hidden="true"></span>
|
||||
<span>{{ sharing.share() ? 'Compartido' : 'Sin compartir' }}</span>
|
||||
</label>
|
||||
<span aria-hidden="true">{{
|
||||
sharing.share() ? 'Compartido' : 'Sin compartir'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (sharing.share(); as share) {
|
||||
@@ -186,53 +186,12 @@ const DEFAULT_BLOCKS: SharedBlock[] = ['flow', 'sprint', 'releases'];
|
||||
color: var(--ts-c-red);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.ts-switch {
|
||||
.ts-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
input:focus-visible + .ts-switch__track {
|
||||
outline: 2px solid var(--ts-brand);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
input:disabled ~ * {
|
||||
opacity: 0.6;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.ts-switch__track {
|
||||
position: relative;
|
||||
width: 2.5rem;
|
||||
height: 1.375rem;
|
||||
border-radius: 999px;
|
||||
background: var(--ts-line-strong);
|
||||
transition: background-color 0.15s ease;
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
border-radius: 50%;
|
||||
background: var(--ts-surface);
|
||||
box-shadow: var(--ts-shadow);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
}
|
||||
.ts-switch input:checked + .ts-switch__track {
|
||||
background: var(--ts-brand);
|
||||
&::after {
|
||||
transform: translateX(1.125rem);
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user