github-issue-tower-defence-management 1.101.6 → 1.101.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/bin/adapter/entry-points/console/ui-dist/assets/index--7aFZNg9.js +101 -0
  3. package/bin/adapter/entry-points/console/ui-dist/assets/index-ES6SLB1Y.css +1 -0
  4. package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
  5. package/package.json +1 -1
  6. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.tsx +139 -145
  7. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +2 -2
  8. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +2 -4
  9. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +1 -4
  10. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +0 -97
  11. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +0 -39
  12. package/src/adapter/entry-points/console/ui/src/index.css +6 -16
  13. package/src/adapter/entry-points/console/ui-dist/assets/index--7aFZNg9.js +101 -0
  14. package/src/adapter/entry-points/console/ui-dist/assets/index-ES6SLB1Y.css +1 -0
  15. package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
  16. package/bin/adapter/entry-points/console/ui-dist/assets/index-D4zghbcI.css +0 -1
  17. package/bin/adapter/entry-points/console/ui-dist/assets/index-DX0mapkS.js +0 -101
  18. package/src/adapter/entry-points/console/ui-dist/assets/index-D4zghbcI.css +0 -1
  19. package/src/adapter/entry-points/console/ui-dist/assets/index-DX0mapkS.js +0 -101
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-outline-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-input:#e5e5e5;--color-ring:#0a0a0a;--color-background:#fff;--color-foreground:#0a0a0a;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary:#f5f5f5;--color-secondary-foreground:#171717;--color-accent:#f5f5f5;--color-accent-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.relative{position:relative}.static{position:static}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.hidden{display:none}.inline-flex{display:inline-flex}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-input{border-color:var(--color-input)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--color-background)}.bg-primary{background-color:var(--color-primary)}.bg-secondary{background-color:var(--color-secondary)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-foreground{color:var(--color-foreground)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.lowercase{text-transform:lowercase}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--color-accent)}.hover\:bg-primary\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--color-primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:#f5f5f5cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--color-secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--color-accent-foreground)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}}body{color:#e6edf3;background-color:#0d1117;margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}.console-app{flex-direction:column;max-width:920px;margin:0 auto;display:flex}.console-tabbar{-webkit-overflow-scrolling:touch;background:#161b22;border-bottom:2px solid #30363d;flex-wrap:nowrap;align-items:stretch;gap:0;min-height:42px;padding:0 8px;display:flex;overflow-x:auto}.console-tab{color:#8b949e;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;margin-bottom:-2px;padding:10px 14px;font-size:13px;font-weight:500;line-height:1.2;text-decoration:none;display:inline-flex}.console-tab:hover{color:#e6edf3}.console-tab[data-active=true]{color:#e6edf3;border-bottom-color:#2f81f7;font-weight:700}.console-tab-badge{text-align:center;color:#e6edf3;background:#484f58;border-radius:20px;min-width:20px;padding:1px 7px;font-size:11px;font-weight:700;line-height:1.5}.console-tab-badge[data-zero=true]{color:#8b949e;background:#30363d}.console-tab-pjname{color:#8b949e;align-self:center;margin-left:auto;padding:0 8px;font-size:11.5px}.console-tab-geninfo{color:#8b949e;align-self:center;padding:0 4px;font-size:11px}.console-list{margin:0;padding:12px 18px 18px;list-style:none}.console-list-group{list-style:none}.console-item-row .console-item-icon{flex:none;margin-top:3px}.console-group-header{background:#0b0f14;border-bottom:1px solid #21262d;justify-content:space-between;align-items:center;padding:6px 12px;display:flex}.console-storytag{align-items:center;gap:8px;font-size:13px;font-weight:700;display:inline-flex}.console-story-dot{border-radius:999px;width:10px;height:10px;display:inline-block}.console-group-count{color:#8b949e;font-size:12px}.console-item-row{color:#e6edf3;text-align:left;cursor:pointer;background:#161b22;border:1px solid #30363d;border-radius:8px;align-items:flex-start;gap:14px;width:100%;margin-bottom:10px;padding:12px 16px;display:flex}.console-item-row:hover{background:#1a2029;border-color:#484f58}.console-item-row[data-active=true]{background:#1a2029;border-color:#4493f8}.console-item-meta{flex:1;min-width:0}.console-item-title{font-size:14.5px;font-weight:600;display:block}.console-item-sub{color:#8b949e;margin-top:3px;font-size:12.5px;display:block}.console-item-pill{color:#8b949e;border:1px solid #30363d;border-radius:20px;margin-right:6px;padding:1px 8px;font-size:11px;display:inline-block}.console-item-createdat{color:#8b949e;cursor:help}.console-item-fields{color:#adbac7;flex-wrap:wrap;gap:4px 10px;margin-top:4px;font-size:11.5px;display:flex}.console-item-field{word-break:break-all;align-items:baseline;gap:4px;min-width:0;display:inline-flex}.console-item-field-label{color:#6e7681;text-transform:uppercase;letter-spacing:.03em;font-size:10px}.console-list-message{color:#8b949e;padding:16px;font-size:14px}.console-list-empty{text-align:center;color:#8b949e;padding:40px;font-size:14px}.console-list-error,.console-comment-error,.console-files-error,.console-commits-error,.console-detail-body-error{color:#f85149}.console-detail{flex-direction:column;gap:12px;padding:16px;display:flex}.console-detail-title{align-items:center;gap:8px;margin:0;font-size:20px;display:flex}.console-detail-title-text{flex:1}.console-detail-number{color:#8b949e;font-weight:400}.console-detail-closed-label{color:#a371f7;font-size:13px}.console-detail-subbar{align-items:center;gap:12px;font-size:13px;display:flex}.console-detail-link{color:#4493f8}.console-detail-repo{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-detail-pill,.console-label-chip,.console-detail-status-chip{border:1px solid #30363d;border-radius:999px;padding:2px 8px;font-size:12px;display:inline-block}.console-detail-labels{flex-wrap:wrap;gap:6px;display:flex}.console-detail-createdat{color:#8b949e;font-size:12px}.console-panel{border:1px solid #30363d;border-radius:8px;overflow:hidden}.console-panel-header{background:#161b22;justify-content:space-between;align-items:center;padding:6px 12px;display:flex}.console-panel-toggle{color:#e6edf3;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;font-size:14px;font-weight:600;display:inline-flex}.console-panel-body{padding:12px}.console-markdown{word-break:break-word;font-size:14px;line-height:1.5}.console-markdown ul{margin:.5em 0;padding-left:1.5em;list-style:outside}.console-markdown ol{margin:.5em 0;padding-left:1.5em;list-style:decimal}.console-markdown li{margin:.25em 0}.console-markdown table{border-collapse:collapse;margin:.5em 0}.console-markdown th,.console-markdown td{border:1px solid #30363d;padding:4px 8px}.console-markdown th{background:#161b22}.console-mermaid-error{color:#f85149;font-size:13px}.console-comment{border-top:1px solid #21262d;padding-top:8px}.console-comment-header{color:#8b949e;gap:8px;font-size:12px;display:flex}.console-comment-author{color:#e6edf3;font-weight:600}.console-files,.console-commits{margin:0;padding:0;list-style:none}.console-commit{align-items:center;gap:8px;padding:4px 0;font-size:13px;display:flex}.console-file{flex-direction:column;font-size:13px;display:flex}.console-file-badge{text-align:center;border:1px solid;border-radius:4px;width:18px;font-size:11px}.console-file-path,.console-commit-message{flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-add,.console-pr-add{color:#3fb950}.console-file-del,.console-pr-del{color:#f85149}.console-commit-sha{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-actionbar{z-index:100;background:#161b22;border-top:2px solid #30363d;padding:10px 16px;position:fixed;bottom:0;left:0;right:0}.console-operation-bar{flex-direction:column;gap:8px;max-width:920px;margin:0 auto;display:flex}.console-op-group{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.console-op-group-review{gap:10px}.console-op-group-stories{max-height:50vh;overflow-y:auto}.console-op-button{color:#e6edf3;white-space:nowrap;cursor:pointer;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:7px 16px;font-size:13px;font-weight:600}.console-op-button:hover{border-color:#484f58}.console-op-button-approve{color:#fff;background:#238636;border-color:#2ea043}.console-op-button-reject{color:#ffd166;background:#7d5000;border-color:#a06800}.console-op-button-wrong{color:#f85149;background:#3a1518;border-color:#f85149}.console-op-button-unneeded{color:#aab0b8;background:#2a2d31;border-color:#6e7681}.console-op-button-snooze{color:#79c0ff;background:#1c2b4a;border-color:#4493f8}.console-pr-section{border:1px solid #30363d;border-radius:8px;flex-direction:column;gap:10px;padding:12px;display:flex}.console-pr-statbar{color:#8b949e;gap:12px;font-size:12px;display:flex}.console-detail-screen{padding-bottom:140px}.console-panel-open-link{color:#4493f8;font-size:13px;font-weight:400}.console-composer{margin-top:4px}.console-composer-toggle{color:#8b949e;cursor:pointer;background:0 0;border:none;padding:2px 0;font-size:12.5px}.console-composer-toggle:hover{color:#e6edf3}.console-composer-posted{flex-direction:column;gap:8px;margin-top:8px;display:flex}.console-composer-form{margin-top:8px}.console-composer-input{box-sizing:border-box;color:#e6edf3;width:100%;font:inherit;resize:vertical;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:8px;font-size:14px}.console-composer-row{align-items:center;gap:8px;margin-top:6px;display:flex}.console-composer-submit{color:#fff;cursor:pointer;background:#238636;border:1px solid #2ea043;border-radius:6px;padding:7px 16px;font-size:13px;font-weight:600}.console-composer-submit:disabled{opacity:.6;cursor:default}.console-composer-status{color:#8b949e;font-size:12px}.console-composer-error{color:#f85149}.console-undo-toast{z-index:9998;white-space:nowrap;border-radius:10px;align-items:center;gap:12px;max-width:92vw;padding:12px 18px;font-size:13.5px;display:flex;position:fixed;top:12px;left:50%;transform:translate(-50%);box-shadow:0 4px 20px #0009}.console-undo-toast-green{color:#3fb950;background:#0d3320;border:1px solid #2ea043}.console-undo-toast-amber{color:#ffd166;background:#3a2800;border:1px solid #a06800}.console-undo-toast-red{color:#f85149;background:#3a1518;border:1px solid #da3633}.console-undo-toast-gray{color:#aab0b8;background:#2a2d31;border:1px solid #6e7681}.console-undo-toast-blue{color:#79c0ff;background:#0d1f40;border:1px solid #4493f8}.console-undo-toast-error{color:#f85149;background:#3a1518;border:1px solid #f85149}.console-undo-toast-message{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.console-undo-toast-undo{cursor:pointer;color:inherit;background:#ffffff1f;border:none;border-radius:6px;flex:none;padding:4px 12px;font-size:13px;font-weight:700}.console-undo-toast-undo:hover{background:#ffffff38}.console-undo-toast-countdown{opacity:.7;flex:none;font-size:11px}.console-undo-toast-bar{opacity:.5;background:currentColor;border-radius:0 0 10px 10px;height:3px;transition:width .1s linear;position:absolute;bottom:0;left:0}.console-file-row{width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:4px 0;font-size:13px;display:flex}.console-file-row:hover{background:#1a2029}.console-file-caret{color:#8b949e;flex:none;width:1em}.console-file-diff{border-collapse:collapse;width:100%;margin:4px 0 8px;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-diff td{white-space:pre-wrap;word-break:break-word;vertical-align:top;padding:0 10px}.console-diff-ln{text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;white-space:nowrap;border-right:1px solid #30363d;width:1%;padding:0 8px}.console-file-diff td.console-diff-ln{white-space:nowrap;word-break:normal;overflow-wrap:normal}.console-diff-add td{background:#2ea04326}.console-diff-add .console-diff-code{color:#aff5b4}.console-diff-del td{background:#f8514926}.console-diff-del .console-diff-code{color:#ffdcd7}.console-diff-hunk td{color:#79c0ff;background:#161b22}.console-diff-ctx .console-diff-code{color:#c9d1d9}.console-file-diff-empty{color:#8b949e;padding:8px 14px;font-size:12px}.console-pr-header{flex-wrap:wrap;align-items:center;gap:10px;padding-top:4px;display:flex}.console-pr-section-title{color:#e6edf3;font-size:15px;font-weight:600}.console-pr-section-state{color:#8b949e;border:1px solid #6e7681;border-radius:999px;padding:1px 8px;font-size:11px}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TDPM Console</title>
7
- <script type="module" crossorigin src="/assets/index-DX0mapkS.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-D4zghbcI.css">
7
+ <script type="module" crossorigin src="/assets/index--7aFZNg9.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-ES6SLB1Y.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "1.101.6",
3
+ "version": "1.101.7",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -1,4 +1,4 @@
1
- import type { ReactNode, Ref } from 'react';
1
+ import type { ReactNode } from 'react';
2
2
  import type { ImageProxyUrlBuilder } from '../../lib/imageProxy';
3
3
  import { colorFromEnum } from '../../logic/colors';
4
4
  import {
@@ -55,7 +55,6 @@ export type ConsoleItemDetailProps = {
55
55
  now: number;
56
56
  commentComposer: ReactNode;
57
57
  operationBar: ReactNode;
58
- scrollRef?: Ref<HTMLElement>;
59
58
  buildImageProxyUrl?: ImageProxyUrlBuilder;
60
59
  };
61
60
 
@@ -81,7 +80,6 @@ export const ConsoleItemDetail = ({
81
80
  now,
82
81
  commentComposer,
83
82
  operationBar,
84
- scrollRef,
85
83
  buildImageProxyUrl,
86
84
  }: ConsoleItemDetailProps) => {
87
85
  const resolvedState = state?.state ?? 'open';
@@ -100,170 +98,166 @@ export const ConsoleItemDetail = ({
100
98
  commitsAreLoading || commitsError !== null ? null : commits.length;
101
99
 
102
100
  return (
103
- <>
104
- <article className="console-detail" ref={scrollRef}>
105
- {storyName !== null && (
106
- <div className="console-detail-story">
107
- <span className="console-storytag">
108
- <span
109
- className="console-story-dot"
110
- style={{ backgroundColor: storyPalette.dot }}
111
- />
112
- {storyName}
113
- </span>
114
- </div>
115
- )}
101
+ <article className="console-detail">
102
+ {storyName !== null && (
103
+ <div className="console-detail-story">
104
+ <span className="console-storytag">
105
+ <span
106
+ className="console-story-dot"
107
+ style={{ backgroundColor: storyPalette.dot }}
108
+ />
109
+ {storyName}
110
+ </span>
111
+ </div>
112
+ )}
116
113
 
117
- {overlayStatus !== null && statusPalette !== null && (
118
- <span
119
- className="console-detail-status-chip"
120
- style={{
121
- color: statusPalette.fg,
122
- borderColor: statusPalette.border,
123
- backgroundColor: statusPalette.bg,
124
- }}
125
- >
126
- {overlayStatus.name}
114
+ {overlayStatus !== null && statusPalette !== null && (
115
+ <span
116
+ className="console-detail-status-chip"
117
+ style={{
118
+ color: statusPalette.fg,
119
+ borderColor: statusPalette.border,
120
+ backgroundColor: statusPalette.bg,
121
+ }}
122
+ >
123
+ {overlayStatus.name}
124
+ </span>
125
+ )}
126
+
127
+ <h2 className="console-detail-title">
128
+ <ConsoleItemIcon
129
+ isPr={item.isPr}
130
+ state={resolvedState}
131
+ merged={merged}
132
+ isDraft={false}
133
+ stateReason=""
134
+ />
135
+ <span className="console-detail-title-text">{item.title}</span>
136
+ <span className="console-detail-number">
137
+ {item.isPr ? `PR #${item.number}` : `#${item.number}`}
138
+ </span>
139
+ {closedStateLabel !== null && (
140
+ <span className="console-detail-closed-label">
141
+ {closedStateLabel}
127
142
  </span>
128
143
  )}
144
+ </h2>
129
145
 
130
- <h2 className="console-detail-title">
131
- <ConsoleItemIcon
132
- isPr={item.isPr}
133
- state={resolvedState}
134
- merged={merged}
135
- isDraft={false}
136
- stateReason=""
137
- />
138
- <span className="console-detail-title-text">{item.title}</span>
139
- <span className="console-detail-number">
140
- {item.isPr ? `PR #${item.number}` : `#${item.number}`}
141
- </span>
142
- {closedStateLabel !== null && (
143
- <span className="console-detail-closed-label">
144
- {closedStateLabel}
146
+ <div className="console-detail-subbar">
147
+ <a
148
+ href={item.url}
149
+ className="console-detail-link"
150
+ target="_blank"
151
+ rel="noopener noreferrer"
152
+ >
153
+ {item.isPr ? `PR #${item.number}` : `Issue #${item.number}`}
154
+ </a>
155
+ <span className="console-detail-repo">{item.repo}</span>
156
+ <span className="console-detail-pill">
157
+ {item.isPr ? 'PR' : 'Issue'}
158
+ </span>
159
+ </div>
160
+
161
+ {item.labels.length > 0 && (
162
+ <div className="console-detail-labels">
163
+ {item.labels.map((label) => (
164
+ <span key={label} className="console-label-chip">
165
+ {label}
145
166
  </span>
146
- )}
147
- </h2>
167
+ ))}
168
+ </div>
169
+ )}
170
+
171
+ <div
172
+ className="console-detail-createdat"
173
+ title={formatFullTimestamp(item.createdAt)}
174
+ >
175
+ opened {formatRelativeTime(item.createdAt, now)}
176
+ </div>
148
177
 
149
- <div className="console-detail-subbar">
178
+ <ConsolePanel
179
+ title="Description"
180
+ headerAction={
150
181
  <a
151
182
  href={item.url}
152
- className="console-detail-link"
183
+ className="console-panel-open-link"
153
184
  target="_blank"
154
185
  rel="noopener noreferrer"
155
186
  >
156
- {item.isPr ? `PR #${item.number}` : `Issue #${item.number}`}
187
+ open
157
188
  </a>
158
- <span className="console-detail-repo">{item.repo}</span>
159
- <span className="console-detail-pill">
160
- {item.isPr ? 'PR' : 'Issue'}
161
- </span>
162
- </div>
163
-
164
- {item.labels.length > 0 && (
165
- <div className="console-detail-labels">
166
- {item.labels.map((label) => (
167
- <span key={label} className="console-label-chip">
168
- {label}
169
- </span>
170
- ))}
171
- </div>
189
+ }
190
+ >
191
+ {bodyError !== null ? (
192
+ <p role="alert" className="console-detail-body-error">
193
+ Failed to load description: {bodyError}
194
+ </p>
195
+ ) : bodyIsLoading ? (
196
+ <p className="console-detail-body-loading">Loading description...</p>
197
+ ) : (
198
+ <ConsoleMarkdownContent
199
+ body={body}
200
+ buildImageProxyUrl={buildImageProxyUrl}
201
+ />
172
202
  )}
203
+ </ConsolePanel>
173
204
 
174
- <div
175
- className="console-detail-createdat"
176
- title={formatFullTimestamp(item.createdAt)}
177
- >
178
- opened {formatRelativeTime(item.createdAt, now)}
179
- </div>
180
-
181
- <ConsolePanel
182
- title="Description"
183
- headerAction={
184
- <a
185
- href={item.url}
186
- className="console-panel-open-link"
187
- target="_blank"
188
- rel="noopener noreferrer"
189
- >
190
- open
191
- </a>
192
- }
193
- >
194
- {bodyError !== null ? (
195
- <p role="alert" className="console-detail-body-error">
196
- Failed to load description: {bodyError}
197
- </p>
198
- ) : bodyIsLoading ? (
199
- <p className="console-detail-body-loading">
200
- Loading description...
201
- </p>
202
- ) : (
203
- <ConsoleMarkdownContent
204
- body={body}
205
- buildImageProxyUrl={buildImageProxyUrl}
206
- />
207
- )}
205
+ {item.isPr && (
206
+ <ConsolePanel title="Changed files" count={filesCount}>
207
+ <ConsoleChangedFileList
208
+ files={files}
209
+ isLoading={filesAreLoading}
210
+ error={filesError}
211
+ />
208
212
  </ConsolePanel>
213
+ )}
209
214
 
210
- {item.isPr && (
211
- <ConsolePanel title="Changed files" count={filesCount}>
212
- <ConsoleChangedFileList
213
- files={files}
214
- isLoading={filesAreLoading}
215
- error={filesError}
216
- />
217
- </ConsolePanel>
218
- )}
215
+ <ConsolePanel
216
+ title="Comments"
217
+ count={commentsCount}
218
+ defaultCollapsed={item.isPr}
219
+ >
220
+ <ConsoleCommentList
221
+ comments={comments}
222
+ isLoading={commentsAreLoading}
223
+ error={commentsError}
224
+ now={now}
225
+ buildImageProxyUrl={buildImageProxyUrl}
226
+ />
227
+ </ConsolePanel>
219
228
 
220
- <ConsolePanel
221
- title="Comments"
222
- count={commentsCount}
223
- defaultCollapsed={item.isPr}
224
- >
225
- <ConsoleCommentList
226
- comments={comments}
227
- isLoading={commentsAreLoading}
228
- error={commentsError}
229
+ {item.isPr && (
230
+ <ConsolePanel title="Commits" count={commitsCount} defaultCollapsed>
231
+ <ConsoleCommitList
232
+ commits={commits}
233
+ isLoading={commitsAreLoading}
234
+ error={commitsError}
229
235
  now={now}
230
- buildImageProxyUrl={buildImageProxyUrl}
231
236
  />
232
237
  </ConsolePanel>
238
+ )}
233
239
 
234
- {item.isPr && (
235
- <ConsolePanel title="Commits" count={commitsCount} defaultCollapsed>
236
- <ConsoleCommitList
237
- commits={commits}
238
- isLoading={commitsAreLoading}
239
- error={commitsError}
240
- now={now}
241
- />
242
- </ConsolePanel>
243
- )}
244
-
245
- {!item.isPr &&
246
- relatedPullRequests.map((related) => (
247
- <ConsolePullRequestDetail
248
- key={related.pullRequest.url}
249
- pullRequest={related.pullRequest}
250
- body={related.pullRequest.summary?.body ?? ''}
251
- bodyIsLoading={false}
252
- files={related.files}
253
- filesAreLoading={related.filesAreLoading}
254
- filesError={related.filesError}
255
- commits={related.commits}
256
- commitsAreLoading={related.commitsAreLoading}
257
- commitsError={related.commitsError}
258
- now={now}
259
- buildImageProxyUrl={buildImageProxyUrl}
260
- />
261
- ))}
240
+ {!item.isPr &&
241
+ relatedPullRequests.map((related) => (
242
+ <ConsolePullRequestDetail
243
+ key={related.pullRequest.url}
244
+ pullRequest={related.pullRequest}
245
+ body={related.pullRequest.summary?.body ?? ''}
246
+ bodyIsLoading={false}
247
+ files={related.files}
248
+ filesAreLoading={related.filesAreLoading}
249
+ filesError={related.filesError}
250
+ commits={related.commits}
251
+ commitsAreLoading={related.commitsAreLoading}
252
+ commitsError={related.commitsError}
253
+ now={now}
254
+ buildImageProxyUrl={buildImageProxyUrl}
255
+ />
256
+ ))}
262
257
 
263
- {commentComposer}
264
- </article>
258
+ {commentComposer}
265
259
 
266
- <footer className="console-actionbar">{operationBar}</footer>
267
- </>
260
+ <div className="console-actionbar">{operationBar}</div>
261
+ </article>
268
262
  );
269
263
  };
@@ -133,7 +133,7 @@ describe('useConsoleOperations', () => {
133
133
  });
134
134
  });
135
135
 
136
- it('does not mark done on snooze outside the todo-by-human tab', async () => {
136
+ it('marks done on snooze outside the todo-by-human tab so the item disappears immediately', async () => {
137
137
  captureFetch();
138
138
  const { result } = setup();
139
139
  await act(async () => {
@@ -145,7 +145,7 @@ describe('useConsoleOperations', () => {
145
145
  const stored = JSON.parse(
146
146
  localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
147
147
  );
148
- expect(stored[issueItem.projectItemId]?.done).toBeUndefined();
148
+ expect(stored[issueItem.projectItemId].done).toBe(true);
149
149
  });
150
150
 
151
151
  it('marks done on snooze in the todo-by-human tab so the item is skipped', async () => {
@@ -146,11 +146,9 @@ export const useConsoleOperations = (
146
146
  projectItemId: item.projectItemId,
147
147
  };
148
148
  await postConsoleOperation(appendToken, TRIAGE_OPERATION_PATH, request);
149
- if (mode === 'todo-by-human') {
150
- markDone(item);
151
- }
149
+ markDone(item);
152
150
  },
153
- [pjcode, appendToken, markDone, mode],
151
+ [pjcode, appendToken, markDone],
154
152
  );
155
153
 
156
154
  const setStory = useCallback(
@@ -1,4 +1,4 @@
1
- import { type Ref, useCallback } from 'react';
1
+ import { useCallback } from 'react';
2
2
  import { ConsoleCommentComposer } from '../components/detail/ConsoleCommentComposer';
3
3
  import { ConsoleItemDetail } from '../components/detail/ConsoleItemDetail';
4
4
  import { ConsoleOperationMenu } from '../components/operations/ConsoleOperationMenu';
@@ -37,7 +37,6 @@ export type ConsoleItemDetailContainerProps = {
37
37
  overlayStatus: ConsoleOverlayStatus | null;
38
38
  now: number;
39
39
  onQueueAction: (input: ConsoleQueueActionInput) => void;
40
- scrollRef?: Ref<HTMLElement>;
41
40
  };
42
41
 
43
42
  export const ConsoleItemDetailContainer = ({
@@ -52,7 +51,6 @@ export const ConsoleItemDetailContainer = ({
52
51
  overlayStatus,
53
52
  now,
54
53
  onQueueAction,
55
- scrollRef,
56
54
  }: ConsoleItemDetailContainerProps) => {
57
55
  const detail = useConsoleItemDetailData(caches, item);
58
56
  const { token } = useConsoleToken();
@@ -150,7 +148,6 @@ export const ConsoleItemDetailContainer = ({
150
148
  commitsError={detail.commitsError}
151
149
  relatedPullRequests={detail.relatedPullRequests}
152
150
  now={now}
153
- scrollRef={scrollRef}
154
151
  buildImageProxyUrl={resolveImageProxyUrl}
155
152
  commentComposer={
156
153
  <ConsoleCommentComposer
@@ -391,103 +391,6 @@ describe('ConsolePage swipe navigation', () => {
391
391
  });
392
392
  });
393
393
 
394
- describe('ConsolePage detail scroll reset', () => {
395
- beforeEach(() => {
396
- localStorage.clear();
397
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
398
- const fetchMock = jest.fn(async (url: string) => {
399
- const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
400
- if (listMatch !== null) {
401
- return {
402
- ok: true,
403
- status: 200,
404
- json: async () =>
405
- listMatch[1] === 'prs'
406
- ? twoItemPrPayload()
407
- : { ...twoItemPrPayload(), items: [] },
408
- };
409
- }
410
- return { ok: true, status: 200, json: async () => ({ body: '# body' }) };
411
- });
412
- global.fetch = fetchMock as unknown as typeof fetch;
413
- });
414
-
415
- it('resets the detail scroll container to the top when navigating to the next item', async () => {
416
- const { container, getByText, findByText } = render(<ConsolePage />);
417
- await waitFor(() => {
418
- expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
419
- });
420
- fireEvent.click(getByText('Add serveConsole subcommand'));
421
- expect(await findByText('Approve')).toBeInTheDocument();
422
-
423
- const scrollContainer = container.querySelector('.console-detail');
424
- expect(scrollContainer).not.toBeNull();
425
- (scrollContainer as HTMLElement).scrollTop = 240;
426
- expect((scrollContainer as HTMLElement).scrollTop).toBe(240);
427
-
428
- const detailScreen = container.querySelector('.console-detail-screen');
429
- swipeDetailScreen(
430
- detailScreen as HTMLElement,
431
- { clientX: 240, clientY: 100 },
432
- { clientX: 40, clientY: 110 },
433
- );
434
-
435
- await waitFor(() => {
436
- expect(window.location.hash).toBe('#item/PVTI_2');
437
- });
438
- await waitFor(() => {
439
- expect((scrollContainer as HTMLElement).scrollTop).toBe(0);
440
- });
441
- });
442
- });
443
-
444
- describe('ConsolePage next item prefetch', () => {
445
- beforeEach(() => {
446
- localStorage.clear();
447
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
448
- });
449
-
450
- it('warms the next pending item resources while the current item is open', async () => {
451
- const fetchMock = jest.fn(async (url: string) => {
452
- const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
453
- if (listMatch !== null) {
454
- return {
455
- ok: true,
456
- status: 200,
457
- json: async () =>
458
- listMatch[1] === 'prs'
459
- ? twoItemPrPayload()
460
- : { ...twoItemPrPayload(), items: [] },
461
- };
462
- }
463
- return { ok: true, status: 200, json: async () => ({ body: '# body' }) };
464
- });
465
- global.fetch = fetchMock as unknown as typeof fetch;
466
-
467
- const { getByText, findByText, queryByText } = render(<ConsolePage />);
468
- await waitFor(() => {
469
- expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
470
- });
471
- fireEvent.click(getByText('Add serveConsole subcommand'));
472
- expect(await findByText('Approve')).toBeInTheDocument();
473
- expect(window.location.hash).toBe('#item/PVTI_1');
474
- expect(queryByText('Add server-side console API handlers')).toBeNull();
475
-
476
- const nextItemUrlFragment = encodeURIComponent(
477
- 'https://github.com/o/r/pull/852',
478
- );
479
- await waitFor(() => {
480
- const calledNextItemBody = fetchMock.mock.calls.some(
481
- ([url]) =>
482
- typeof url === 'string' &&
483
- url.includes('/api/itembody') &&
484
- url.includes(nextItemUrlFragment),
485
- );
486
- expect(calledNextItemBody).toBe(true);
487
- });
488
- });
489
- });
490
-
491
394
  describe('ConsolePage auto-advance', () => {
492
395
  beforeEach(() => {
493
396
  localStorage.clear();
@@ -191,44 +191,6 @@ export const ConsolePage = () => {
191
191
  );
192
192
 
193
193
  const detailScreenRef = useConsoleSwipeNavigation(handleSwipe);
194
- const detailScrollElementRef = useRef<HTMLElement | null>(null);
195
-
196
- useEffect(() => {
197
- if (selectedItemKey === null) {
198
- return;
199
- }
200
- const element = detailScrollElementRef.current;
201
- if (element !== null) {
202
- element.scrollTop = 0;
203
- }
204
- }, [selectedItemKey]);
205
-
206
- const nextPendingItem = useMemo<ConsoleListItem | null>(() => {
207
- if (selectedItemKey === null) {
208
- return null;
209
- }
210
- const nextKey = nextPendingKeyBrowse(orderedPendingKeys, selectedItemKey);
211
- if (nextKey === null) {
212
- return null;
213
- }
214
- return (
215
- pendingItems.find((item) => overlayKeyForItem(item) === nextKey) ?? null
216
- );
217
- }, [selectedItemKey, orderedPendingKeys, pendingItems]);
218
-
219
- useEffect(() => {
220
- if (nextPendingItem === null) {
221
- return;
222
- }
223
- const key = `${nextPendingItem.repo}#${nextPendingItem.number}`;
224
- const url = nextPendingItem.url;
225
- void caches.body.load(key, url);
226
- void caches.state.load(key, url);
227
- if (nextPendingItem.isPr) {
228
- void caches.files.load(key, url);
229
- void caches.commits.load(key, url);
230
- }
231
- }, [nextPendingItem, caches]);
232
194
 
233
195
  return (
234
196
  <main className="console-app">
@@ -273,7 +235,6 @@ export const ConsolePage = () => {
273
235
  overlayStatus={overlayStatusForSelected}
274
236
  now={now}
275
237
  onQueueAction={handleQueueAction}
276
- scrollRef={detailScrollElementRef}
277
238
  />
278
239
  </div>
279
240
  )}