fix(web): a poll asks its own question instead of a stock one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -301,14 +301,14 @@ visualización de la plataforma:
|
|||||||
## 4.6 Rutas
|
## 4.6 Rutas
|
||||||
|
|
||||||
| Ruta | Página |
|
| Ruta | Página |
|
||||||
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `/login` | Inicio de sesión (solo sin sesión) |
|
| `/login` | Inicio de sesión (solo sin sesión) |
|
||||||
| `/auth/callback` | Retorno de Pireon (PKCE) |
|
| `/auth/callback` | Retorno de Pireon (PKCE) |
|
||||||
| `/` | Inicio: saludo según la hora con el resumen del día, «Ir a…» (`WEB-12`), primeros pasos, mis proyectos con su actividad (lo primero, para llegar antes), «Mi día» (`ts-my-day`: los tickets que elijo para hoy, tachados al terminar, mis abiertos para añadir y lo que quedó del último día), mis fijados (`ts-pinned`, una franja que se quita con ×; solo si hay), cuatro cifras (`ts-home-kpis`: abiertos míos, esperando QA, terminados por mí y por el equipo esta semana), la semana (`ts-week-agenda`), mis vistas guardadas y dos columnas: mis tickets y lo último en mis proyectos; sprints en curso, esperando QA, que sigo, próximas releases, quién está ahora y «Retomar» |
|
| `/` | Inicio: saludo según la hora con el resumen del día, «Ir a…» (`WEB-12`), primeros pasos, mis proyectos con su actividad (lo primero, para llegar antes), «Mi día» (`ts-my-day`: los tickets que elijo para hoy, tachados al terminar, mis abiertos para añadir y lo que quedó del último día), mis fijados (`ts-pinned`, una franja que se quita con ×; solo si hay), cuatro cifras (`ts-home-kpis`: abiertos míos, esperando QA, terminados por mí y por el equipo esta semana), la semana (`ts-week-agenda`), mis vistas guardadas y dos columnas: mis tickets y lo último en mis proyectos; sprints en curso, esperando QA, que sigo, próximas releases, quién está ahora y «Retomar» |
|
||||||
| `/portfolio` | Cartera (con sesión): una tarjeta por proyecto activo con lo abierto y en riesgo, el sprint en curso (¿llega?), las próximas releases con su previsión y las épicas abiertas; en directo: se vuelve a leer sola cuando cambia un ticket, sprint o release de esos proyectos. Cada proyecto lleva su semáforo de salud (`portfolioHealth`), con las causas al pasar por encima |
|
| `/portfolio` | Cartera (con sesión): una tarjeta por proyecto activo con lo abierto y en riesgo, el sprint en curso (¿llega?), las próximas releases con su previsión y las épicas abiertas; en directo: se vuelve a leer sola cuando cambia un ticket, sprint o release de esos proyectos. Cada proyecto lleva su semáforo de salud (`portfolioHealth`), con las causas al pasar por encima |
|
||||||
| `/explore` | Proyectos públicos (sin sesión) |
|
| `/explore` | Proyectos públicos (sin sesión) |
|
||||||
| `/p/:key/board` | Tablero kanban (`?release=` y `?assignee=` preseleccionan los filtros). Quien puede contribuir cambia prioridad, estimación y persona desde la propia tarjeta (selectores nativos sobre sus distintivos; el título es el enlace). Mover una tarjeta o cambiar su persona ofrece «Deshacer» unos segundos (o Ctrl/⌘ Z): la orden contraria, que el flujo puede rechazar. Con el teclado: Tab entra en las tarjetas, las flechas se mueven entre ellas, Shift+←/→ pasa la tarjeta de columna (mismas reglas que arrastrar), `p`/`e`/`a` abren su prioridad, estimación o persona y Enter la abre |
|
| `/p/:key/board` | Tablero kanban (`?release=` y `?assignee=` preseleccionan los filtros). Quien puede contribuir cambia prioridad, estimación y persona desde la propia tarjeta (selectores nativos sobre sus distintivos; el título es el enlace). Mover una tarjeta o cambiar su persona ofrece «Deshacer» unos segundos (o Ctrl/⌘ Z): la orden contraria, que el flujo puede rechazar. Con el teclado: Tab entra en las tarjetas, las flechas se mueven entre ellas, Shift+←/→ pasa la tarjeta de columna (mismas reglas que arrastrar), `p`/`e`/`a` abren su prioridad, estimación o persona y Enter la abre |
|
||||||
| `/p/:key/issues/:issueKey` | Ticket. Encima del título, quién más lo está viendo o editando ahora (`PresenceFacade`: late cada 10 s; editar es tener abierto el formulario del ticket o de un comentario, o estar escribiendo uno). A la vista, «Votar», «Seguir» y «Editar»; el resto (pedir revisión, mi día, recordármelo, seguir todo, fijar y duplicar) está en el menú «Más» (menú del CDK: se recorre con las flechas y Escape lo cierra). «Fijar» lo deja a mano en el inicio y en la paleta de búsqueda. Arriba, sus decisiones (comentarios marcados con la bandera por quien puede cambiar el ticket); `?comment=<id>` lleva a un comentario y lo señala. Cambiar el estado o la persona y mandarlo a la papelera (sin confirmación) ofrecen «Deshacer». Cada conversación con respuestas se resuelve («✓ Resolver», con una conclusión opcional que queda como decisión) y se pliega en una línea; la cabecera cuenta las abiertas y terminar el ticket con alguna pregunta antes. Se ve quién está escribiendo en cada conversación («Ana está escribiendo…», `PresenceFacade.typists`), y en las respuestas Enter envía (Shift+Enter, otra línea). Si tiene subtareas, «Seguir todo» avisa de ella y de todo lo que cuelga, también lo que se añada (también desde Épicas). «Recordármelo» pone un aviso solo para mí (dentro de 1 hora, esta tarde, mañana o el lunes a las 9, en una semana o cuando diga), con nota opcional. «☀ Mi día» lo añade a los de hoy. «Pedir revisión» a alguien del equipo: lo ve en «Mi trabajo» («Te piden revisión») y responde «Todo bien» o «Pedir cambios» desde el recuadro Revisiones. Un comentario puede llevar una encuesta («Encuesta»; con ella el botón pasa a «Publicar encuesta», y basta con dos opciones): se vota pulsando una opción y, al cerrarla, la ganadora queda como decisión. «🎥 Grabar pantalla» (con la voz, si se da permiso al micrófono) y «🎙 Grabar audio» graban en el navegador hasta 3 minutos y lo adjuntan al comentario, que puede ir sin texto; los vídeos y audios adjuntos se reproducen ahí mismo. Al abrirlo, lo que otros han hecho desde tu última visita: un aviso arriba («Desde tu última visita, hace 2 días: 3 comentarios y 1 cambio de Ana y Bob», con «Ver lo nuevo»), los comentarios nuevos marcados («Nuevo», también en una conversación plegada) y los cambios del historial resaltados. Cada comentario se puede «Convertir en ticket» (subtarea de este o enlazado, con el título sacado de su primera línea): el comentario enlaza al ticket nuevo («→ Convertido en WEB-45») |
|
| `/p/:key/issues/:issueKey` | Ticket. Encima del título, quién más lo está viendo o editando ahora (`PresenceFacade`: late cada 10 s; editar es tener abierto el formulario del ticket o de un comentario, o estar escribiendo uno). A la vista, «Votar», «Seguir» y «Editar»; el resto (pedir revisión, mi día, recordármelo, seguir todo, fijar y duplicar) está en el menú «Más» (menú del CDK: se recorre con las flechas y Escape lo cierra). «Fijar» lo deja a mano en el inicio y en la paleta de búsqueda. Arriba, sus decisiones (comentarios marcados con la bandera por quien puede cambiar el ticket); `?comment=<id>` lleva a un comentario y lo señala. Cambiar el estado o la persona y mandarlo a la papelera (sin confirmación) ofrecen «Deshacer». Cada conversación con respuestas se resuelve («✓ Resolver», con una conclusión opcional que queda como decisión) y se pliega en una línea; la cabecera cuenta las abiertas y terminar el ticket con alguna pregunta antes. Se ve quién está escribiendo en cada conversación («Ana está escribiendo…», `PresenceFacade.typists`), y en las respuestas Enter envía (Shift+Enter, otra línea). Si tiene subtareas, «Seguir todo» avisa de ella y de todo lo que cuelga, también lo que se añada (también desde Épicas). «Recordármelo» pone un aviso solo para mí (dentro de 1 hora, esta tarde, mañana o el lunes a las 9, en una semana o cuando diga), con nota opcional. «☀ Mi día» lo añade a los de hoy. «Pedir revisión» a alguien del equipo: lo ve en «Mi trabajo» («Te piden revisión») y responde «Todo bien» o «Pedir cambios» desde el recuadro Revisiones. Un comentario puede llevar una encuesta («Encuesta»; con su pregunta y de 2 a 6 opciones; el botón pasa a «Publicar encuesta» y el texto del comentario es opcional): se vota pulsando una opción y, al cerrarla, la ganadora queda como decisión. «🎥 Grabar pantalla» (con la voz, si se da permiso al micrófono) y «🎙 Grabar audio» graban en el navegador hasta 3 minutos y lo adjuntan al comentario, que puede ir sin texto; los vídeos y audios adjuntos se reproducen ahí mismo. Al abrirlo, lo que otros han hecho desde tu última visita: un aviso arriba («Desde tu última visita, hace 2 días: 3 comentarios y 1 cambio de Ana y Bob», con «Ver lo nuevo»), los comentarios nuevos marcados («Nuevo», también en una conversación plegada) y los cambios del historial resaltados. Cada comentario se puede «Convertir en ticket» (subtarea de este o enlazado, con el título sacado de su primera línea): el comentario enlaza al ticket nuevo («→ Convertido en WEB-45») |
|
||||||
| `/p/:key/releases` | Releases. «Página pública» (quien gestiona): un enlace secreto con las notas para clientes, que se copia, renueva o retira |
|
| `/p/:key/releases` | Releases. «Página pública» (quien gestiona): un enlace secreto con las notas para clientes, que se copia, renueva o retira |
|
||||||
| `/p/:key/report/:kind/:id` | Informe para imprimir de un sprint (`sprint`) o una release (`release`): datos, totales, notas y tickets por etapa. «Imprimir o guardar en PDF» abre el diálogo del navegador; al imprimir se quitan la cabecera, las pestañas y los fondos (`styles.scss`) |
|
| `/p/:key/report/:kind/:id` | Informe para imprimir de un sprint (`sprint`) o una release (`release`): datos, totales, notas y tickets por etapa. «Imprimir o guardar en PDF» abre el diálogo del navegador; al imprimir se quitan la cabecera, las pestañas y los fondos (`styles.scss`) |
|
||||||
| `/p/:key/roadmap` | Hoja de ruta: épicas en el tiempo, con sprints y releases; flechas «bloquea» / «depende de» entre épicas y aviso si una empieza antes de que acabe la que la bloquea. Los bloqueos con tickets de otros proyectos (en los dos sentidos, `externalDependencies`) salen en «De otros proyectos» con barra discontinua, sus flechas y el mismo aviso si las fechas no encajan; los que no tienen fechas o no se pueden leer se nombran debajo |
|
| `/p/:key/roadmap` | Hoja de ruta: épicas en el tiempo, con sprints y releases; flechas «bloquea» / «depende de» entre épicas y aviso si una empieza antes de que acabe la que la bloquea. Los bloqueos con tickets de otros proyectos (en los dos sentidos, `externalDependencies`) salen en «De otros proyectos» con barra discontinua, sus flechas y el mismo aviso si las fechas no encajan; los que no tienen fechas o no se pueden leer se nombran debajo |
|
||||||
|
|||||||
@@ -1365,9 +1365,16 @@ const MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|||||||
<fieldset class="ts-poll-editor">
|
<fieldset class="ts-poll-editor">
|
||||||
<legend>Encuesta · de 2 a 6 opciones</legend>
|
<legend>Encuesta · de 2 a 6 opciones</legend>
|
||||||
<p class="ts-poll-editor__hint">
|
<p class="ts-poll-editor__hint">
|
||||||
La pregunta va en el texto de arriba. Se publica con el
|
Se publica con el comentario, al pulsar «Publicar
|
||||||
comentario, al pulsar «Publicar encuesta».
|
encuesta». El texto de arriba es opcional.
|
||||||
</p>
|
</p>
|
||||||
|
<pi-text-field
|
||||||
|
placeholder="¿Stripe o Redsys para los pagos?"
|
||||||
|
[value]="pollQuestion()"
|
||||||
|
(valueChange)="pollQuestion.set($event.slice(0, 200))"
|
||||||
|
>
|
||||||
|
<pi-label [isRequired]="true">Pregunta</pi-label>
|
||||||
|
</pi-text-field>
|
||||||
@for (option of pollOptions(); track $index) {
|
@for (option of pollOptions(); track $index) {
|
||||||
<div class="ts-poll-editor__row">
|
<div class="ts-poll-editor__row">
|
||||||
<pi-text-field
|
<pi-text-field
|
||||||
@@ -1446,7 +1453,7 @@ const MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|||||||
[text]="pollOn() ? 'Publicar encuesta' : 'Comentar'"
|
[text]="pollOn() ? 'Publicar encuesta' : 'Comentar'"
|
||||||
[disabled]="
|
[disabled]="
|
||||||
pollOn()
|
pollOn()
|
||||||
? pollReady() < 2
|
? !pollQuestion().trim() || pollReady() < 2
|
||||||
: !commentBody().trim() && !commentFiles().length
|
: !commentBody().trim() && !commentFiles().length
|
||||||
"
|
"
|
||||||
(execute)="addComment()"
|
(execute)="addComment()"
|
||||||
@@ -2583,11 +2590,12 @@ export class IssuePage {
|
|||||||
|
|
||||||
protected addComment(): void {
|
protected addComment(): void {
|
||||||
const files = this.commentFiles();
|
const files = this.commentFiles();
|
||||||
// Only files (a recording, say) need no words: their names say it.
|
const text = this.commentBody().trim();
|
||||||
|
const question = this.pollOn() ? this.pollQuestion().trim() : '';
|
||||||
|
// A poll's question heads the comment; the text, if any, follows.
|
||||||
const body =
|
const body =
|
||||||
this.commentBody().trim() ||
|
(question ? `**${question}**${text ? `\n\n${text}` : ''}` : text) ||
|
||||||
// A poll alone asks its own question.
|
// Only files (a recording, say) need no words: their names say it.
|
||||||
(this.pollOn() ? '📊 ¿Qué opción preferís?' : '') ||
|
|
||||||
(files.length === 1
|
(files.length === 1
|
||||||
? `📎 ${files[0].name}`
|
? `📎 ${files[0].name}`
|
||||||
: files.length
|
: files.length
|
||||||
@@ -2597,6 +2605,10 @@ export class IssuePage {
|
|||||||
const options = this.pollOptions()
|
const options = this.pollOptions()
|
||||||
.map((o) => o.trim())
|
.map((o) => o.trim())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
if (this.pollOn() && !question) {
|
||||||
|
this.toast.error('Escribe la pregunta de la encuesta');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.pollOn() && options.length < 2) {
|
if (this.pollOn() && options.length < 2) {
|
||||||
this.toast.error('Una encuesta necesita al menos dos opciones');
|
this.toast.error('Una encuesta necesita al menos dos opciones');
|
||||||
return;
|
return;
|
||||||
@@ -2609,6 +2621,7 @@ export class IssuePage {
|
|||||||
|
|
||||||
/** A quick poll in the new comment: its options while it is written. */
|
/** A quick poll in the new comment: its options while it is written. */
|
||||||
protected readonly pollOn = signal(false);
|
protected readonly pollOn = signal(false);
|
||||||
|
protected readonly pollQuestion = signal('');
|
||||||
protected readonly pollOptions = signal<string[]>(['', '']);
|
protected readonly pollOptions = signal<string[]>(['', '']);
|
||||||
/** Options written so far: two make a poll ready to publish. */
|
/** Options written so far: two make a poll ready to publish. */
|
||||||
protected readonly pollReady = computed(
|
protected readonly pollReady = computed(
|
||||||
@@ -2616,6 +2629,7 @@ export class IssuePage {
|
|||||||
);
|
);
|
||||||
|
|
||||||
protected startPoll(): void {
|
protected startPoll(): void {
|
||||||
|
this.pollQuestion.set('');
|
||||||
this.pollOptions.set(['', '']);
|
this.pollOptions.set(['', '']);
|
||||||
this.pollOn.set(true);
|
this.pollOn.set(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user