@masterteam/discussion 0.0.5 → 0.0.6
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.
package/assets/discussion.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@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-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--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;--tw-outline-style:solid}}}@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;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-emerald-600:oklch(59.6% .145 163.225);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-sm:.25rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--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)}}@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%;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;-webkit-text-decoration: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]){appearance:button}::file-selector-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{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.bottom-1{bottom:calc(var(--spacing) * 1)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.mx-1{margin-inline:calc(var(--spacing) * 1)}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-px{margin-top:1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-1{margin-left:calc(var(--spacing) * 1)}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.hidden{display:none}.inline-flex{display:inline-flex}.h-6{height:calc(var(--spacing) * 6)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-\[1\.9rem\]{height:1.9rem}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-\[55vh\]{max-height:55vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[3\.75rem\]{min-height:3.75rem}.min-h-\[5\.25rem\]{min-height:5.25rem}.w-6{width:calc(var(--spacing) * 6)}.w-\[1\.9rem\]{width:1.9rem}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\[12rem\]{max-width:12rem}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-56{min-width:calc(var(--spacing) * 56)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-bottom-left{transform-origin:0 100%}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[0\.65rem\]{border-radius:.65rem}.rounded-\[1\.5rem\]{border-radius:1.5rem}.rounded-\[1\.35rem\]{border-radius:1.35rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_18\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_18\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 18%,transparent)}}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_20\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_20\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 20%,transparent)}}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_26\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_26\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 26%,transparent)}}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.border-surface-300{border-color:var(--p-surface-300)}@supports (color:color-mix(in lab, red, red)){.border-surface-300{border-color:color-mix(in srgb, var(--p-surface-300) calc(100% * 1), transparent)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_7\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_7\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 7%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 11%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_12\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_12\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 12%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_16\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_16\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 16%,white)}}.bg-primary-50{background-color:var(--p-primary-50)}@supports (color:color-mix(in lab, red, red)){.bg-primary-50{background-color:color-mix(in srgb, var(--p-primary-50) calc(100% * 1), transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-surface-0{background-color:var(--p-surface-0)}@supports (color:color-mix(in lab, red, red)){.bg-surface-0{background-color:color-mix(in srgb, var(--p-surface-0) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.bg-surface-50\/60{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50\/60{background-color:color-mix(in oklab, color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent) 60%, transparent)}}.bg-surface-100{background-color:var(--p-surface-100)}@supports (color:color-mix(in lab, red, red)){.bg-surface-100{background-color:color-mix(in srgb, var(--p-surface-100) calc(100% * 1), transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-8{padding:calc(var(--spacing) * 8)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.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)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-24{padding-right:calc(var(--spacing) * 24)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.text-center{text-align:center}.text-left{text-align:left}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.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))}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.9rem\]{font-size:.9rem}.text-\[0\.67rem\]{font-size:.67rem}.text-\[0\.72rem\]{font-size:.72rem}.text-\[0\.73rem\]{font-size:.73rem}.text-\[0\.74rem\]{font-size:.74rem}.text-\[0\.78rem\]{font-size:.78rem}.text-\[0\.79rem\]{font-size:.79rem}.text-\[0\.86rem\]{font-size:.86rem}.text-\[11px\]{font-size:11px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.25\]{--tw-leading:1.25;line-height:1.25}.leading-\[1\.45\]{--tw-leading:1.45;line-height:1.45}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.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)}.break-words{overflow-wrap:break-word}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 74%,black)}}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_75\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_75\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 75%,black)}}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_76\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_76\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 76%,black)}}.text-emerald-600{color:var(--color-emerald-600)}.text-primary-700{color:var(--p-primary-700)}@supports (color:color-mix(in lab, red, red)){.text-primary-700{color:color-mix(in srgb, var(--p-primary-700) calc(100% * 1), transparent)}}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-surface-500{color:var(--p-surface-500)}@supports (color:color-mix(in lab, red, red)){.text-surface-500{color:color-mix(in srgb, var(--p-surface-500) calc(100% * 1), transparent)}}.text-surface-600{color:var(--p-surface-600)}@supports (color:color-mix(in lab, red, red)){.text-surface-600{color:color-mix(in srgb, var(--p-surface-600) calc(100% * 1), transparent)}}.text-surface-700{color:var(--p-surface-700)}@supports (color:color-mix(in lab, red, red)){.text-surface-700{color:color-mix(in srgb, var(--p-surface-700) calc(100% * 1), transparent)}}.text-surface-900{color:var(--p-surface-900)}@supports (color:color-mix(in lab, red, red)){.text-surface-900{color:color-mix(in srgb, var(--p-surface-900) calc(100% * 1), transparent)}}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_24\%\,transparent\)\]:hover{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_24\%\,transparent\)\]:hover{border-color:color-mix(in srgb,var(--p-primary-color) 24%,transparent)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_8\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_8\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 8%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_10\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_10\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 10%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 11%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_17\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_17\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 17%,white)}}.hover\:bg-surface-50:hover{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-50:hover{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.hover\:bg-surface-100:hover{background-color:var(--p-surface-100)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-100:hover{background-color:color-mix(in srgb, var(--p-surface-100) calc(100% * 1), transparent)}}.hover\:text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]:hover{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]:hover{color:color-mix(in srgb,var(--p-primary-color) 74%,black)}}}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\:outline-\[color-mix\(in_srgb\,var\(--p-primary-color\)_32\%\,transparent\)\]:focus-visible{outline-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:outline-\[color-mix\(in_srgb\,var\(--p-primary-color\)_32\%\,transparent\)\]:focus-visible{outline-color:color-mix(in srgb,var(--p-primary-color) 32%,transparent)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-55:disabled{opacity:.55}@media (min-width:40rem){.sm\:max-w-\[90\%\]{max-width:90%}}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@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}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes pulse{50%{opacity:.5}}
|
|
2
|
+
@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-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--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;--tw-outline-style:solid}}}@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;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-emerald-600:oklch(59.6% .145 163.225);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-sm:.25rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--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)}}@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%;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;-webkit-text-decoration: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]){appearance:button}::file-selector-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{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.bottom-1{bottom:calc(var(--spacing) * 1)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.mx-1{margin-inline:calc(var(--spacing) * 1)}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-px{margin-top:1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.hidden{display:none}.inline-flex{display:inline-flex}.h-6{height:calc(var(--spacing) * 6)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-\[1\.9rem\]{height:1.9rem}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-\[55vh\]{max-height:55vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[3\.75rem\]{min-height:3.75rem}.min-h-\[5\.25rem\]{min-height:5.25rem}.w-6{width:calc(var(--spacing) * 6)}.w-\[1\.9rem\]{width:1.9rem}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\[12rem\]{max-width:12rem}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-56{min-width:calc(var(--spacing) * 56)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-bottom-left{transform-origin:0 100%}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[0\.65rem\]{border-radius:.65rem}.rounded-\[1\.5rem\]{border-radius:1.5rem}.rounded-\[1\.35rem\]{border-radius:1.35rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_18\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_18\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 18%,transparent)}}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_20\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_20\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 20%,transparent)}}.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_26\%\,transparent\)\]{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_26\%\,transparent\)\]{border-color:color-mix(in srgb,var(--p-primary-color) 26%,transparent)}}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.border-surface-300{border-color:var(--p-surface-300)}@supports (color:color-mix(in lab, red, red)){.border-surface-300{border-color:color-mix(in srgb, var(--p-surface-300) calc(100% * 1), transparent)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_7\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_7\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 7%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 11%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_12\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_12\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 12%,white)}}.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_16\%\,white\)\]{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_16\%\,white\)\]{background-color:color-mix(in srgb,var(--p-primary-color) 16%,white)}}.bg-primary-50{background-color:var(--p-primary-50)}@supports (color:color-mix(in lab, red, red)){.bg-primary-50{background-color:color-mix(in srgb, var(--p-primary-50) calc(100% * 1), transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-surface-0{background-color:var(--p-surface-0)}@supports (color:color-mix(in lab, red, red)){.bg-surface-0{background-color:color-mix(in srgb, var(--p-surface-0) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.bg-surface-50\/60{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50\/60{background-color:color-mix(in oklab, color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent) 60%, transparent)}}.bg-surface-100{background-color:var(--p-surface-100)}@supports (color:color-mix(in lab, red, red)){.bg-surface-100{background-color:color-mix(in srgb, var(--p-surface-100) calc(100% * 1), transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-8{padding:calc(var(--spacing) * 8)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.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)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-24{padding-right:calc(var(--spacing) * 24)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.text-center{text-align:center}.text-left{text-align:left}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.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))}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.9rem\]{font-size:.9rem}.text-\[0\.67rem\]{font-size:.67rem}.text-\[0\.72rem\]{font-size:.72rem}.text-\[0\.73rem\]{font-size:.73rem}.text-\[0\.74rem\]{font-size:.74rem}.text-\[0\.78rem\]{font-size:.78rem}.text-\[0\.79rem\]{font-size:.79rem}.text-\[0\.86rem\]{font-size:.86rem}.text-\[11px\]{font-size:11px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.25\]{--tw-leading:1.25;line-height:1.25}.leading-\[1\.45\]{--tw-leading:1.45;line-height:1.45}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.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)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 74%,black)}}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_75\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_75\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 75%,black)}}.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_76\%\,black\)\]{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_76\%\,black\)\]{color:color-mix(in srgb,var(--p-primary-color) 76%,black)}}.text-emerald-600{color:var(--color-emerald-600)}.text-primary-700{color:var(--p-primary-700)}@supports (color:color-mix(in lab, red, red)){.text-primary-700{color:color-mix(in srgb, var(--p-primary-700) calc(100% * 1), transparent)}}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-surface-500{color:var(--p-surface-500)}@supports (color:color-mix(in lab, red, red)){.text-surface-500{color:color-mix(in srgb, var(--p-surface-500) calc(100% * 1), transparent)}}.text-surface-600{color:var(--p-surface-600)}@supports (color:color-mix(in lab, red, red)){.text-surface-600{color:color-mix(in srgb, var(--p-surface-600) calc(100% * 1), transparent)}}.text-surface-700{color:var(--p-surface-700)}@supports (color:color-mix(in lab, red, red)){.text-surface-700{color:color-mix(in srgb, var(--p-surface-700) calc(100% * 1), transparent)}}.text-surface-900{color:var(--p-surface-900)}@supports (color:color-mix(in lab, red, red)){.text-surface-900{color:color-mix(in srgb, var(--p-surface-900) calc(100% * 1), transparent)}}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_24\%\,transparent\)\]:hover{border-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:border-\[color-mix\(in_srgb\,var\(--p-primary-color\)_24\%\,transparent\)\]:hover{border-color:color-mix(in srgb,var(--p-primary-color) 24%,transparent)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_8\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_8\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 8%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_10\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_10\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 10%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_11\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 11%,white)}}.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_17\%\,white\)\]:hover{background-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--p-primary-color\)_17\%\,white\)\]:hover{background-color:color-mix(in srgb,var(--p-primary-color) 17%,white)}}.hover\:bg-surface-50:hover{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-50:hover{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.hover\:bg-surface-100:hover{background-color:var(--p-surface-100)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-100:hover{background-color:color-mix(in srgb, var(--p-surface-100) calc(100% * 1), transparent)}}.hover\:text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]:hover{color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.hover\:text-\[color-mix\(in_srgb\,var\(--p-primary-color\)_74\%\,black\)\]:hover{color:color-mix(in srgb,var(--p-primary-color) 74%,black)}}}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\:outline-\[color-mix\(in_srgb\,var\(--p-primary-color\)_32\%\,transparent\)\]:focus-visible{outline-color:var(--p-primary-color)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:outline-\[color-mix\(in_srgb\,var\(--p-primary-color\)_32\%\,transparent\)\]:focus-visible{outline-color:color-mix(in srgb,var(--p-primary-color) 32%,transparent)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-55:disabled{opacity:.55}@media (min-width:40rem){.sm\:max-w-\[90\%\]{max-width:90%}.sm\:shrink-0{flex-shrink:0}.sm\:flex-row{flex-direction:row}.sm\:flex-nowrap{flex-wrap:nowrap}.sm\:items-start{align-items:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:text-right{text-align:right}}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@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}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes pulse{50%{opacity:.5}}
|
|
@@ -1618,7 +1618,7 @@ class DiscussionThread {
|
|
|
1618
1618
|
return `${fileName}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
1619
1619
|
}
|
|
1620
1620
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DiscussionThread, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1621
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DiscussionThread, isStandalone: true, selector: "mt-discussion-thread", inputs: { moduleType: { classPropertyName: "moduleType", publicName: "moduleType", isSignal: true, isRequired: true, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, currentUserId: { classPropertyName: "currentUserId", publicName: "currentUserId", isSignal: true, isRequired: false, transformFunction: null }, requestContext: { classPropertyName: "requestContext", publicName: "requestContext", isSignal: true, isRequired: false, transformFunction: null }, mentionableUsers: { classPropertyName: "mentionableUsers", publicName: "mentionableUsers", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchEndpoint: { classPropertyName: "mentionSearchEndpoint", publicName: "mentionSearchEndpoint", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchParam: { classPropertyName: "mentionSearchParam", publicName: "mentionSearchParam", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchDataPath: { classPropertyName: "mentionSearchDataPath", publicName: "mentionSearchDataPath", isSignal: true, isRequired: false, transformFunction: null }, allowAttachments: { classPropertyName: "allowAttachments", publicName: "allowAttachments", isSignal: true, isRequired: false, transformFunction: null }, uploadEndpoint: { classPropertyName: "uploadEndpoint", publicName: "uploadEndpoint", isSignal: true, isRequired: false, transformFunction: null }, attachmentDownloadEndpoint: { classPropertyName: "attachmentDownloadEndpoint", publicName: "attachmentDownloadEndpoint", isSignal: true, isRequired: false, transformFunction: null }, showParticipants: { classPropertyName: "showParticipants", publicName: "showParticipants", isSignal: true, isRequired: false, transformFunction: null }, autoMarkRead: { classPropertyName: "autoMarkRead", publicName: "autoMarkRead", isSignal: true, isRequired: false, transformFunction: null }, refreshIntervalMs: { classPropertyName: "refreshIntervalMs", publicName: "refreshIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", errored: "errored", commentCreated: "commentCreated", commentUpdated: "commentUpdated", commentDeleted: "commentDeleted", readStateChanged: "readStateChanged" }, host: { classAttribute: "block h-full min-h-0" }, viewQueries: [{ propertyName: "viewportRef", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "composerInputRef", first: true, predicate: ["composerInput"], descendants: true, isSignal: true }, { propertyName: "attachmentInputRef", first: true, predicate: ["attachmentInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n class=\"mt-discussion-card h-full min-h-0 w-full overflow-hidden shadow-sm\"\r\n [paddingless]=\"true\"\r\n [ngClass]=\"styleClass()\"\r\n>\r\n <div class=\"flex h-full min-h-0 flex-col overflow-hidden\">\r\n <input\r\n #attachmentInput\r\n type=\"file\"\r\n class=\"hidden\"\r\n multiple\r\n (change)=\"onAttachmentSelected($event)\"\r\n />\r\n\r\n <header\r\n class=\"flex items-center justify-between gap-3 border-b border-surface-200 bg-surface-0 px-4 py-3.5\"\r\n >\r\n <div class=\"min-w-0 flex-1 flex items-center gap-2\">\r\n <div class=\"text-2xl text-surface-500 font-semibold\">\r\n <mt-icon icon=\"communication.message-chat-square\"></mt-icon>\r\n </div>\r\n <h3 class=\"truncate text-base font-semibold text-surface-900\">\r\n {{ title() }}\r\n </h3>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [loading]=\"refreshing()\"\r\n [disabled]=\"loadingInitial() || markingRead()\"\r\n (onClick)=\"actionsPopover.toggle($event)\"\r\n />\r\n\r\n <p-popover\r\n #actionsPopover\r\n appendTo=\"body\"\r\n styleClass=\"mt-discussion-actions-popover\"\r\n >\r\n <div class=\"flex min-w-44 flex-col py-1\">\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"refreshing() || loadingInitial()\"\r\n (click)=\"actionsPopover.hide(); refreshThread()\"\r\n >\r\n <mt-icon icon=\"arrow.refresh-cw-01\"></mt-icon>\r\n\r\n <span>{{ refreshing() ? \"Refreshing...\" : \"Refresh\" }}</span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"markingRead() || !hasUnread()\"\r\n (click)=\"actionsPopover.hide(); markRead()\"\r\n >\r\n <mt-icon icon=\"general.check\"></mt-icon>\r\n\r\n <span>Mark read</span>\r\n </button>\r\n\r\n @if (showParticipants()) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100\"\r\n (click)=\"actionsPopover.hide(); toggleParticipantsPanel()\"\r\n >\r\n <mt-icon icon=\"user.users-01\"></mt-icon>\r\n\r\n <span>{{\r\n participantsExpanded()\r\n ? \"Hide participants\"\r\n : \"Show participants\"\r\n }}</span>\r\n </button>\r\n }\r\n </div>\r\n </p-popover>\r\n </div>\r\n </header>\r\n\r\n @if (showParticipants() && participantsExpanded()) {\r\n <section class=\"border-b border-surface-200 px-4 py-3\">\r\n @if (participantsLoading()) {\r\n <span class=\"text-xs text-surface-500\">Loading participants...</span>\r\n } @else if (participantEntities().length === 0) {\r\n <span class=\"text-xs text-surface-500\">No participants yet.</span>\r\n } @else {\r\n <div class=\"max-h-48 overflow-y-auto pr-1\">\r\n <mt-entities-preview [entities]=\"participantEntities()\" />\r\n </div>\r\n }\r\n </section>\r\n }\r\n\r\n @if (errorMessage(); as error) {\r\n <div\r\n class=\"border-b border-red-200 bg-red-50 px-4 py-2 text-sm text-red-700\"\r\n >\r\n {{ error }}\r\n </div>\r\n }\r\n\r\n <div class=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\r\n <div\r\n #viewport\r\n class=\"min-h-0 flex-1 space-y-3 overflow-x-hidden overflow-y-auto overscroll-contain bg-surface-50/60 px-3 py-3\"\r\n (scroll)=\"onViewportScroll()\"\r\n >\r\n @if (hasMore()) {\r\n <div class=\"flex justify-center py-1\">\r\n <mt-button\r\n icon=\"arrow.chevron-up\"\r\n [label]=\"loadingMore() ? 'Loading...' : 'Load older messages'\"\r\n size=\"small\"\r\n [outlined]=\"true\"\r\n [loading]=\"loadingMore()\"\r\n (onClick)=\"loadOlder()\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (loadingInitial()) {\r\n <div class=\"space-y-2\">\r\n @for (item of [1, 2, 3, 4]; track item) {\r\n <div class=\"h-16 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (commentsAsc().length === 0) {\r\n <div class=\"rounded-2xl p-8 text-center\">\r\n <h4 class=\"text-sm font-semibold text-surface-700\">\r\n No comments yet\r\n </h4>\r\n <p class=\"mt-1 text-xs text-surface-500\">Start the conversation.</p>\r\n </div>\r\n } @else {\r\n @for (comment of commentsAsc(); track trackComment($index, comment)) {\r\n @if (firstUnreadCommentId() === comment.id) {\r\n <div class=\"my-1 flex items-center justify-center gap-2\">\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n <span\r\n class=\"rounded-full border border-red-200 bg-red-50 px-2 py-0.5 text-[0.67rem] font-bold leading-none text-red-700\"\r\n >Unread messages</span\r\n >\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n </div>\r\n }\r\n\r\n <article\r\n class=\"group flex gap-2\"\r\n [class.justify-end]=\"isOwnComment(comment)\"\r\n >\r\n @if (!isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"w-fit min-w-0 max-w-full rounded-[1.35rem] border border-surface-200 bg-white px-3 py-2.5 sm:max-w-[90%]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_7%,white)]]=\"\r\n isOwnComment(comment)\r\n \"\r\n >\r\n <div\r\n class=\"mb-1 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <div\r\n class=\"text-xs w-full text-surface-600 flex justify-between\"\r\n >\r\n <div class=\"font-semibold text-surface-900\">\r\n {{ comment.createdBy }}\r\n </div>\r\n <div>\r\n <span>{{\r\n comment.createdAt | date: \"MMM d, y h:mm a\"\r\n }}</span>\r\n @if (comment.updatedAt) {\r\n <span class=\"ml-1 text-[11px] text-surface-500\"\r\n >(edited)</span\r\n >\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (getParentComment(comment); as parentComment) {\r\n <button\r\n type=\"button\"\r\n class=\"mb-2 block w-full rounded-xl border border-surface-200 bg-surface-50 px-2 py-1 text-left text-xs text-surface-600\"\r\n (click)=\"openReply(parentComment)\"\r\n >\r\n <span class=\"font-semibold\">{{\r\n parentComment.createdBy\r\n }}</span>\r\n <span class=\"mx-1\">:</span>\r\n <span class=\"line-clamp-1\">{{\r\n parentComment.comment\r\n }}</span>\r\n </button>\r\n }\r\n\r\n @if (editingCommentId() === comment.id) {\r\n <div class=\"relative\">\r\n <textarea\r\n rows=\"3\"\r\n class=\"w-full min-h-[5.25rem] resize-y rounded-2xl border border-surface-300 bg-white px-3 py-2.5 text-[0.86rem] leading-[1.45] text-surface-900 outline-none focus-visible:outline-2 focus-visible:outline-[color-mix(in_srgb,var(--p-primary-color)_32%,transparent)] focus-visible:outline-offset-1\"\r\n [ngModel]=\"editText()\"\r\n (ngModelChange)=\"editText.set($event)\"\r\n (input)=\"onEditInput($event)\"\r\n (keyup)=\"onEditCaretEvent($event)\"\r\n (click)=\"onEditCaretEvent($event)\"\r\n (scroll)=\"onEditCaretEvent($event)\"\r\n (keydown)=\"onEditKeydown($event)\"\r\n ></textarea>\r\n\r\n @if (\r\n mentionSession()?.mode === \"edit\" &&\r\n mentionSession()?.editCommentId === comment.id\r\n ) {\r\n <div\r\n class=\"absolute top-0 left-0 z-20 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span\r\n class=\"flex min-w-0 flex-1 flex-col gap-0.5\"\r\n >\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"mt-2 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <span class=\"text-xs text-surface-500\"\r\n >{{ editText().length }}/10000</span\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-surface-300 bg-transparent px-3 py-2 text-xs font-semibold leading-none text-surface-700 transition-colors hover:border-[color-mix(in_srgb,var(--p-primary-color)_24%,transparent)] hover:bg-[color-mix(in_srgb,var(--p-primary-color)_8%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"cancelEdit()\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-[color-mix(in_srgb,var(--p-primary-color)_26%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_12%,white)] px-3 py-2 text-xs font-bold leading-none text-[color-mix(in_srgb,var(--p-primary-color)_76%,black)] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_17%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"!canSaveEdit()\"\r\n (click)=\"saveEdit()\"\r\n >\r\n {{ savingEdit() ? \"Saving...\" : \"Save\" }}\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"whitespace-pre-wrap pt-1 break-words text-sm leading-6\"\r\n >\r\n @for (\r\n segment of getCommentSegments(comment);\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n [attr.data-user-id]=\"segment.userId || null\"\r\n >\r\n {{ segment.text }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (comment.attachments.length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2\">\r\n @for (\r\n attachment of comment.attachments;\r\n track attachment.id\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex max-w-full items-center gap-1.5 rounded-lg border border-surface-300 px-2 py-1 text-[0.72rem] hover:bg-surface-50\"\r\n (click)=\"downloadAttachment(comment, attachment)\"\r\n >\r\n <span class=\"truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n <span class=\"text-[11px] text-surface-500\"\r\n >({{ attachment.size | number }} bytes)</span\r\n >\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"mt-2 flex flex-wrap items-center gap-1\">\r\n @if (!comment.isSystem) {\r\n <button\r\n type=\"button\"\r\n class=\"cursor-pointer rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openReply(comment)\"\r\n >\r\n Reply\r\n </button>\r\n }\r\n @if (canEditComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"startEdit(comment)\"\r\n >\r\n Edit\r\n </button>\r\n }\r\n @if (canDeleteComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-red-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"isDeleting(comment.id)\"\r\n (click)=\"deleteComment(comment)\"\r\n >\r\n {{ isDeleting(comment.id) ? \"Deleting...\" : \"Delete\" }}\r\n </button>\r\n }\r\n @if (comment.updatedAt) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openRevisions(comment)\"\r\n >\r\n History\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n </article>\r\n }\r\n }\r\n </div>\r\n\r\n <footer\r\n class=\"z-10 shrink-0 border-t border-surface-200 bg-content px-3 py-3\"\r\n >\r\n @if (replyToComment(); as replyComment) {\r\n <div\r\n class=\"mb-2 flex items-center justify-between rounded-xl border border-surface-200 bg-surface-50 px-2 py-1\"\r\n >\r\n <div class=\"min-w-0 text-xs text-surface-600\">\r\n <span class=\"font-semibold\"\r\n >Replying to {{ replyComment.createdBy }}</span\r\n >\r\n <p class=\"truncate\">{{ replyComment.comment }}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"clearReply()\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"rounded-[1.5rem] border border-surface-300 bg-white p-2.5 shadow-sm\"\r\n >\r\n <div class=\"relative\">\r\n <textarea\r\n #composerInput\r\n rows=\"2\"\r\n class=\"w-full min-h-[3.75rem] resize-none border-0 bg-transparent px-2 pb-10 pr-24 pt-1 text-[0.9rem] leading-[1.45] text-surface-900 outline-none\"\r\n [disabled]=\"disabled() || posting()\"\r\n [ngModel]=\"composerText()\"\r\n (ngModelChange)=\"composerText.set($event)\"\r\n (input)=\"onComposerInput($event)\"\r\n (keyup)=\"onComposerCaretEvent($event)\"\r\n (click)=\"onComposerCaretEvent($event)\"\r\n (scroll)=\"onComposerCaretEvent($event)\"\r\n (keydown)=\"onComposerKeydown($event)\"\r\n [placeholder]=\"placeholder()\"\r\n ></textarea>\r\n\r\n <div class=\"absolute right-1 bottom-1 flex items-center gap-2\">\r\n @if (allowAttachments()) {\r\n <mt-button\r\n icon=\"file.paperclip\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [disabled]=\"disabled() || posting()\"\r\n (onClick)=\"browseAttachments()\"\r\n />\r\n }\r\n\r\n <mt-button\r\n icon=\"communication.send-01\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-send-btn\"\r\n [loading]=\"posting()\"\r\n [disabled]=\"!canSend()\"\r\n (onClick)=\"sendComment()\"\r\n />\r\n </div>\r\n\r\n @if (mentionSession()?.mode === \"composer\") {\r\n <div\r\n class=\"absolute top-0 left-0 z-30 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (composerAttachments().length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2 px-1\">\r\n @for (attachment of composerAttachments(); track attachment.id) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-2.5 py-1.5 text-xs\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"max-w-[12rem] truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n @if (attachment.status === \"uploading\") {\r\n <span class=\"text-surface-500\"\r\n >{{ attachment.progress }}%</span\r\n >\r\n } @else if (attachment.status === \"failed\") {\r\n <span class=\"text-red-600\">Failed</span>\r\n } @else {\r\n <span class=\"text-emerald-600\">Ready</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"removeAttachment(attachment.id)\"\r\n >\r\n Remove\r\n </button>\r\n </div>\r\n @if (attachment.error) {\r\n <p class=\"text-[11px] text-red-600\">\r\n {{ attachment.error }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (composerText().length > 10000) {\r\n <div class=\"mt-2 px-1 text-xs font-medium text-red-600\">\r\n Comment cannot exceed 10000 characters.\r\n </div>\r\n }\r\n </div>\r\n </footer>\r\n </div>\r\n </div>\r\n</mt-card>\r\n\r\n<p-dialog\r\n [visible]=\"revisionsDialogVisible()\"\r\n (visibleChange)=\"revisionsDialogVisible.set($event)\"\r\n [modal]=\"true\"\r\n [dismissableMask]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: 'min(42rem, 92vw)' }\"\r\n header=\"Comment history\"\r\n>\r\n @if (revisionLoading()) {\r\n <div class=\"space-y-2\">\r\n @for (row of [1, 2, 3]; track row) {\r\n <div class=\"h-12 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (visibleRevisions().length === 0) {\r\n <p class=\"text-sm text-surface-500\">No revision snapshots.</p>\r\n } @else {\r\n <div class=\"max-h-[55vh] space-y-2 overflow-y-auto pr-1\">\r\n @for (revision of visibleRevisions(); track revision.id) {\r\n <article class=\"rounded-xl border border-surface-200 p-3\">\r\n <div class=\"mb-1 text-xs text-surface-500\">\r\n Revision #{{ revision.revisionNumber }} •\r\n {{ revision.createdAt | date: \"MMM d, y h:mm a\" }} •\r\n {{ revision.createdBy }}\r\n </div>\r\n <div class=\"whitespace-pre-wrap break-words text-sm leading-6\">\r\n @for (\r\n segment of getCommentSegments({\r\n id: revision.id,\r\n moduleType: selectedRevisionComment()?.moduleType || \"\",\r\n recordId: selectedRevisionComment()?.recordId || 0,\r\n parentCommentId: null,\r\n comment: revision.comment,\r\n isSystem: false,\r\n createdAt: revision.createdAt,\r\n updatedAt: null,\r\n createdBy: revision.createdBy,\r\n updatedBy: null,\r\n attachments: [],\r\n mentions: revision.mentions,\r\n });\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n >{{ segment.text }}</span\r\n >\r\n }\r\n </div>\r\n </article>\r\n }\r\n </div>\r\n }\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div{display:flex;flex-direction:column;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div>div.flex-1{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}:host ::ng-deep .mt-discussion-actions-popover .p-popover-content{padding:.25rem}:host ::ng-deep .mt-discussion-icon-btn,:host ::ng-deep .mt-discussion-send-btn{height:2.25rem;width:2.25rem;min-width:2.25rem}:host ::ng-deep .mt-discussion-send-btn{box-shadow:0 10px 24px color-mix(in srgb,var(--p-primary-color) 22%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1621
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DiscussionThread, isStandalone: true, selector: "mt-discussion-thread", inputs: { moduleType: { classPropertyName: "moduleType", publicName: "moduleType", isSignal: true, isRequired: true, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, currentUserId: { classPropertyName: "currentUserId", publicName: "currentUserId", isSignal: true, isRequired: false, transformFunction: null }, requestContext: { classPropertyName: "requestContext", publicName: "requestContext", isSignal: true, isRequired: false, transformFunction: null }, mentionableUsers: { classPropertyName: "mentionableUsers", publicName: "mentionableUsers", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchEndpoint: { classPropertyName: "mentionSearchEndpoint", publicName: "mentionSearchEndpoint", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchParam: { classPropertyName: "mentionSearchParam", publicName: "mentionSearchParam", isSignal: true, isRequired: false, transformFunction: null }, mentionSearchDataPath: { classPropertyName: "mentionSearchDataPath", publicName: "mentionSearchDataPath", isSignal: true, isRequired: false, transformFunction: null }, allowAttachments: { classPropertyName: "allowAttachments", publicName: "allowAttachments", isSignal: true, isRequired: false, transformFunction: null }, uploadEndpoint: { classPropertyName: "uploadEndpoint", publicName: "uploadEndpoint", isSignal: true, isRequired: false, transformFunction: null }, attachmentDownloadEndpoint: { classPropertyName: "attachmentDownloadEndpoint", publicName: "attachmentDownloadEndpoint", isSignal: true, isRequired: false, transformFunction: null }, showParticipants: { classPropertyName: "showParticipants", publicName: "showParticipants", isSignal: true, isRequired: false, transformFunction: null }, autoMarkRead: { classPropertyName: "autoMarkRead", publicName: "autoMarkRead", isSignal: true, isRequired: false, transformFunction: null }, refreshIntervalMs: { classPropertyName: "refreshIntervalMs", publicName: "refreshIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", errored: "errored", commentCreated: "commentCreated", commentUpdated: "commentUpdated", commentDeleted: "commentDeleted", readStateChanged: "readStateChanged" }, host: { classAttribute: "block h-full min-h-0" }, viewQueries: [{ propertyName: "viewportRef", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "composerInputRef", first: true, predicate: ["composerInput"], descendants: true, isSignal: true }, { propertyName: "attachmentInputRef", first: true, predicate: ["attachmentInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n class=\"mt-discussion-card h-full min-h-0 w-full overflow-hidden shadow-sm\"\r\n [paddingless]=\"true\"\r\n [ngClass]=\"styleClass()\"\r\n>\r\n <div class=\"flex h-full min-h-0 flex-col overflow-hidden\">\r\n <input\r\n #attachmentInput\r\n type=\"file\"\r\n class=\"hidden\"\r\n multiple\r\n (change)=\"onAttachmentSelected($event)\"\r\n />\r\n\r\n <header\r\n class=\"flex items-center justify-between gap-3 border-b border-surface-200 bg-surface-0 px-4 py-3.5\"\r\n >\r\n <div class=\"min-w-0 flex-1 flex items-center gap-2\">\r\n <div class=\"text-2xl text-surface-500 font-semibold\">\r\n <mt-icon icon=\"communication.message-chat-square\"></mt-icon>\r\n </div>\r\n <h3 class=\"truncate text-base font-semibold text-surface-900\">\r\n {{ title() }}\r\n </h3>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [loading]=\"refreshing()\"\r\n [disabled]=\"loadingInitial() || markingRead()\"\r\n (onClick)=\"actionsPopover.toggle($event)\"\r\n />\r\n\r\n <p-popover\r\n #actionsPopover\r\n appendTo=\"body\"\r\n styleClass=\"mt-discussion-actions-popover\"\r\n >\r\n <div class=\"flex min-w-44 flex-col py-1\">\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"refreshing() || loadingInitial()\"\r\n (click)=\"actionsPopover.hide(); refreshThread()\"\r\n >\r\n <mt-icon icon=\"arrow.refresh-cw-01\"></mt-icon>\r\n\r\n <span>{{ refreshing() ? \"Refreshing...\" : \"Refresh\" }}</span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"markingRead() || !hasUnread()\"\r\n (click)=\"actionsPopover.hide(); markRead()\"\r\n >\r\n <mt-icon icon=\"general.check\"></mt-icon>\r\n\r\n <span>Mark read</span>\r\n </button>\r\n\r\n @if (showParticipants()) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100\"\r\n (click)=\"actionsPopover.hide(); toggleParticipantsPanel()\"\r\n >\r\n <mt-icon icon=\"user.users-01\"></mt-icon>\r\n\r\n <span>{{\r\n participantsExpanded()\r\n ? \"Hide participants\"\r\n : \"Show participants\"\r\n }}</span>\r\n </button>\r\n }\r\n </div>\r\n </p-popover>\r\n </div>\r\n </header>\r\n\r\n @if (showParticipants() && participantsExpanded()) {\r\n <section class=\"border-b border-surface-200 px-4 py-3\">\r\n @if (participantsLoading()) {\r\n <span class=\"text-xs text-surface-500\">Loading participants...</span>\r\n } @else if (participantEntities().length === 0) {\r\n <span class=\"text-xs text-surface-500\">No participants yet.</span>\r\n } @else {\r\n <div class=\"max-h-48 overflow-y-auto pr-1\">\r\n <mt-entities-preview [entities]=\"participantEntities()\" />\r\n </div>\r\n }\r\n </section>\r\n }\r\n\r\n @if (errorMessage(); as error) {\r\n <div\r\n class=\"border-b border-red-200 bg-red-50 px-4 py-2 text-sm text-red-700\"\r\n >\r\n {{ error }}\r\n </div>\r\n }\r\n\r\n <div class=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\r\n <div\r\n #viewport\r\n class=\"min-h-0 flex-1 space-y-3 overflow-x-hidden overflow-y-auto overscroll-contain bg-surface-50/60 px-3 py-3\"\r\n (scroll)=\"onViewportScroll()\"\r\n >\r\n @if (hasMore()) {\r\n <div class=\"flex justify-center py-1\">\r\n <mt-button\r\n icon=\"arrow.chevron-up\"\r\n [label]=\"loadingMore() ? 'Loading...' : 'Load older messages'\"\r\n size=\"small\"\r\n [outlined]=\"true\"\r\n [loading]=\"loadingMore()\"\r\n (onClick)=\"loadOlder()\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (loadingInitial()) {\r\n <div class=\"space-y-2\">\r\n @for (item of [1, 2, 3, 4]; track item) {\r\n <div class=\"h-16 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (commentsAsc().length === 0) {\r\n <div class=\"rounded-2xl p-8 text-center\">\r\n <h4 class=\"text-sm font-semibold text-surface-700\">\r\n No comments yet\r\n </h4>\r\n <p class=\"mt-1 text-xs text-surface-500\">Start the conversation.</p>\r\n </div>\r\n } @else {\r\n @for (comment of commentsAsc(); track trackComment($index, comment)) {\r\n @if (firstUnreadCommentId() === comment.id) {\r\n <div class=\"my-1 flex items-center justify-center gap-2\">\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n <span\r\n class=\"rounded-full border border-red-200 bg-red-50 px-2 py-0.5 text-[0.67rem] font-bold leading-none text-red-700\"\r\n >Unread messages</span\r\n >\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n </div>\r\n }\r\n\r\n <article\r\n class=\"group flex gap-2\"\r\n [class.justify-end]=\"isOwnComment(comment)\"\r\n >\r\n @if (!isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"w-fit min-w-0 max-w-full rounded-[1.35rem] border border-surface-200 bg-white px-3 py-2.5 sm:max-w-[90%]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_7%,white)]]=\"\r\n isOwnComment(comment)\r\n \"\r\n >\r\n <div\n class=\"mb-1 flex flex-col gap-1 text-xs text-surface-600 sm:flex-row sm:items-start sm:justify-between sm:gap-3\"\n >\n <div class=\"min-w-0 break-words font-semibold text-surface-900\">\n {{ comment.createdBy }}\n </div>\n <div\n class=\"inline-flex flex-wrap items-center gap-1 text-surface-500 sm:shrink-0 sm:flex-nowrap sm:text-right\"\n >\n <span class=\"whitespace-nowrap\">{{\n comment.createdAt | date: \"MMM d, y h:mm a\"\n }}</span>\n @if (comment.updatedAt) {\n <span class=\"whitespace-nowrap text-[11px] text-surface-500\"\n >(edited)</span\n >\n }\n </div>\n </div>\n\r\n @if (getParentComment(comment); as parentComment) {\r\n <button\r\n type=\"button\"\r\n class=\"mb-2 block w-full rounded-xl border border-surface-200 bg-surface-50 px-2 py-1 text-left text-xs text-surface-600\"\r\n (click)=\"openReply(parentComment)\"\r\n >\r\n <span class=\"font-semibold\">{{\r\n parentComment.createdBy\r\n }}</span>\r\n <span class=\"mx-1\">:</span>\r\n <span class=\"line-clamp-1\">{{\r\n parentComment.comment\r\n }}</span>\r\n </button>\r\n }\r\n\r\n @if (editingCommentId() === comment.id) {\r\n <div class=\"relative\">\r\n <textarea\r\n rows=\"3\"\r\n class=\"w-full min-h-[5.25rem] resize-y rounded-2xl border border-surface-300 bg-white px-3 py-2.5 text-[0.86rem] leading-[1.45] text-surface-900 outline-none focus-visible:outline-2 focus-visible:outline-[color-mix(in_srgb,var(--p-primary-color)_32%,transparent)] focus-visible:outline-offset-1\"\r\n [ngModel]=\"editText()\"\r\n (ngModelChange)=\"editText.set($event)\"\r\n (input)=\"onEditInput($event)\"\r\n (keyup)=\"onEditCaretEvent($event)\"\r\n (click)=\"onEditCaretEvent($event)\"\r\n (scroll)=\"onEditCaretEvent($event)\"\r\n (keydown)=\"onEditKeydown($event)\"\r\n ></textarea>\r\n\r\n @if (\r\n mentionSession()?.mode === \"edit\" &&\r\n mentionSession()?.editCommentId === comment.id\r\n ) {\r\n <div\r\n class=\"absolute top-0 left-0 z-20 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span\r\n class=\"flex min-w-0 flex-1 flex-col gap-0.5\"\r\n >\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"mt-2 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <span class=\"text-xs text-surface-500\"\r\n >{{ editText().length }}/10000</span\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-surface-300 bg-transparent px-3 py-2 text-xs font-semibold leading-none text-surface-700 transition-colors hover:border-[color-mix(in_srgb,var(--p-primary-color)_24%,transparent)] hover:bg-[color-mix(in_srgb,var(--p-primary-color)_8%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"cancelEdit()\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-[color-mix(in_srgb,var(--p-primary-color)_26%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_12%,white)] px-3 py-2 text-xs font-bold leading-none text-[color-mix(in_srgb,var(--p-primary-color)_76%,black)] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_17%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"!canSaveEdit()\"\r\n (click)=\"saveEdit()\"\r\n >\r\n {{ savingEdit() ? \"Saving...\" : \"Save\" }}\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"whitespace-pre-wrap pt-1 break-words text-sm leading-6\"\r\n >\r\n @for (\r\n segment of getCommentSegments(comment);\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n [attr.data-user-id]=\"segment.userId || null\"\r\n >\r\n {{ segment.text }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (comment.attachments.length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2\">\r\n @for (\r\n attachment of comment.attachments;\r\n track attachment.id\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex max-w-full items-center gap-1.5 rounded-lg border border-surface-300 px-2 py-1 text-[0.72rem] hover:bg-surface-50\"\r\n (click)=\"downloadAttachment(comment, attachment)\"\r\n >\r\n <span class=\"truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n <span class=\"text-[11px] text-surface-500\"\r\n >({{ attachment.size | number }} bytes)</span\r\n >\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"mt-2 flex flex-wrap items-center gap-1\">\r\n @if (!comment.isSystem) {\r\n <button\r\n type=\"button\"\r\n class=\"cursor-pointer rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openReply(comment)\"\r\n >\r\n Reply\r\n </button>\r\n }\r\n @if (canEditComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"startEdit(comment)\"\r\n >\r\n Edit\r\n </button>\r\n }\r\n @if (canDeleteComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-red-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"isDeleting(comment.id)\"\r\n (click)=\"deleteComment(comment)\"\r\n >\r\n {{ isDeleting(comment.id) ? \"Deleting...\" : \"Delete\" }}\r\n </button>\r\n }\r\n @if (comment.updatedAt) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openRevisions(comment)\"\r\n >\r\n History\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n </article>\r\n }\r\n }\r\n </div>\r\n\r\n <footer\r\n class=\"z-10 shrink-0 border-t border-surface-200 bg-content px-3 py-3\"\r\n >\r\n @if (replyToComment(); as replyComment) {\r\n <div\r\n class=\"mb-2 flex items-center justify-between rounded-xl border border-surface-200 bg-surface-50 px-2 py-1\"\r\n >\r\n <div class=\"min-w-0 text-xs text-surface-600\">\r\n <span class=\"font-semibold\"\r\n >Replying to {{ replyComment.createdBy }}</span\r\n >\r\n <p class=\"truncate\">{{ replyComment.comment }}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"clearReply()\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"rounded-[1.5rem] border border-surface-300 bg-white p-2.5 shadow-sm\"\r\n >\r\n <div class=\"relative\">\r\n <textarea\r\n #composerInput\r\n rows=\"2\"\r\n class=\"w-full min-h-[3.75rem] resize-none border-0 bg-transparent px-2 pb-10 pr-24 pt-1 text-[0.9rem] leading-[1.45] text-surface-900 outline-none\"\r\n [disabled]=\"disabled() || posting()\"\r\n [ngModel]=\"composerText()\"\r\n (ngModelChange)=\"composerText.set($event)\"\r\n (input)=\"onComposerInput($event)\"\r\n (keyup)=\"onComposerCaretEvent($event)\"\r\n (click)=\"onComposerCaretEvent($event)\"\r\n (scroll)=\"onComposerCaretEvent($event)\"\r\n (keydown)=\"onComposerKeydown($event)\"\r\n [placeholder]=\"placeholder()\"\r\n ></textarea>\r\n\r\n <div class=\"absolute right-1 bottom-1 flex items-center gap-2\">\r\n @if (allowAttachments()) {\r\n <mt-button\r\n icon=\"file.paperclip\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [disabled]=\"disabled() || posting()\"\r\n (onClick)=\"browseAttachments()\"\r\n />\r\n }\r\n\r\n <mt-button\r\n icon=\"communication.send-01\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-send-btn\"\r\n [loading]=\"posting()\"\r\n [disabled]=\"!canSend()\"\r\n (onClick)=\"sendComment()\"\r\n />\r\n </div>\r\n\r\n @if (mentionSession()?.mode === \"composer\") {\r\n <div\r\n class=\"absolute top-0 left-0 z-30 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (composerAttachments().length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2 px-1\">\r\n @for (attachment of composerAttachments(); track attachment.id) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-2.5 py-1.5 text-xs\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"max-w-[12rem] truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n @if (attachment.status === \"uploading\") {\r\n <span class=\"text-surface-500\"\r\n >{{ attachment.progress }}%</span\r\n >\r\n } @else if (attachment.status === \"failed\") {\r\n <span class=\"text-red-600\">Failed</span>\r\n } @else {\r\n <span class=\"text-emerald-600\">Ready</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"removeAttachment(attachment.id)\"\r\n >\r\n Remove\r\n </button>\r\n </div>\r\n @if (attachment.error) {\r\n <p class=\"text-[11px] text-red-600\">\r\n {{ attachment.error }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (composerText().length > 10000) {\r\n <div class=\"mt-2 px-1 text-xs font-medium text-red-600\">\r\n Comment cannot exceed 10000 characters.\r\n </div>\r\n }\r\n </div>\r\n </footer>\r\n </div>\r\n </div>\r\n</mt-card>\r\n\r\n<p-dialog\r\n [visible]=\"revisionsDialogVisible()\"\r\n (visibleChange)=\"revisionsDialogVisible.set($event)\"\r\n [modal]=\"true\"\r\n [dismissableMask]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: 'min(42rem, 92vw)' }\"\r\n header=\"Comment history\"\r\n>\r\n @if (revisionLoading()) {\r\n <div class=\"space-y-2\">\r\n @for (row of [1, 2, 3]; track row) {\r\n <div class=\"h-12 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (visibleRevisions().length === 0) {\r\n <p class=\"text-sm text-surface-500\">No revision snapshots.</p>\r\n } @else {\r\n <div class=\"max-h-[55vh] space-y-2 overflow-y-auto pr-1\">\r\n @for (revision of visibleRevisions(); track revision.id) {\r\n <article class=\"rounded-xl border border-surface-200 p-3\">\r\n <div class=\"mb-1 text-xs text-surface-500\">\r\n Revision #{{ revision.revisionNumber }} •\r\n {{ revision.createdAt | date: \"MMM d, y h:mm a\" }} •\r\n {{ revision.createdBy }}\r\n </div>\r\n <div class=\"whitespace-pre-wrap break-words text-sm leading-6\">\r\n @for (\r\n segment of getCommentSegments({\r\n id: revision.id,\r\n moduleType: selectedRevisionComment()?.moduleType || \"\",\r\n recordId: selectedRevisionComment()?.recordId || 0,\r\n parentCommentId: null,\r\n comment: revision.comment,\r\n isSystem: false,\r\n createdAt: revision.createdAt,\r\n updatedAt: null,\r\n createdBy: revision.createdBy,\r\n updatedBy: null,\r\n attachments: [],\r\n mentions: revision.mentions,\r\n });\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n >{{ segment.text }}</span\r\n >\r\n }\r\n </div>\r\n </article>\r\n }\r\n </div>\r\n }\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div{display:flex;flex-direction:column;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div>div.flex-1{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}:host ::ng-deep .mt-discussion-actions-popover .p-popover-content{padding:.25rem}:host ::ng-deep .mt-discussion-icon-btn,:host ::ng-deep .mt-discussion-send-btn{height:2.25rem;width:2.25rem;min-width:2.25rem}:host ::ng-deep .mt-discussion-send-btn{box-shadow:0 10px 24px color-mix(in srgb,var(--p-primary-color) 22%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1622
1622
|
}
|
|
1623
1623
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DiscussionThread, decorators: [{
|
|
1624
1624
|
type: Component,
|
|
@@ -1634,7 +1634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1634
1634
|
Icon,
|
|
1635
1635
|
], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1636
1636
|
class: 'block h-full min-h-0',
|
|
1637
|
-
}, template: "<mt-card\r\n class=\"mt-discussion-card h-full min-h-0 w-full overflow-hidden shadow-sm\"\r\n [paddingless]=\"true\"\r\n [ngClass]=\"styleClass()\"\r\n>\r\n <div class=\"flex h-full min-h-0 flex-col overflow-hidden\">\r\n <input\r\n #attachmentInput\r\n type=\"file\"\r\n class=\"hidden\"\r\n multiple\r\n (change)=\"onAttachmentSelected($event)\"\r\n />\r\n\r\n <header\r\n class=\"flex items-center justify-between gap-3 border-b border-surface-200 bg-surface-0 px-4 py-3.5\"\r\n >\r\n <div class=\"min-w-0 flex-1 flex items-center gap-2\">\r\n <div class=\"text-2xl text-surface-500 font-semibold\">\r\n <mt-icon icon=\"communication.message-chat-square\"></mt-icon>\r\n </div>\r\n <h3 class=\"truncate text-base font-semibold text-surface-900\">\r\n {{ title() }}\r\n </h3>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [loading]=\"refreshing()\"\r\n [disabled]=\"loadingInitial() || markingRead()\"\r\n (onClick)=\"actionsPopover.toggle($event)\"\r\n />\r\n\r\n <p-popover\r\n #actionsPopover\r\n appendTo=\"body\"\r\n styleClass=\"mt-discussion-actions-popover\"\r\n >\r\n <div class=\"flex min-w-44 flex-col py-1\">\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"refreshing() || loadingInitial()\"\r\n (click)=\"actionsPopover.hide(); refreshThread()\"\r\n >\r\n <mt-icon icon=\"arrow.refresh-cw-01\"></mt-icon>\r\n\r\n <span>{{ refreshing() ? \"Refreshing...\" : \"Refresh\" }}</span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"markingRead() || !hasUnread()\"\r\n (click)=\"actionsPopover.hide(); markRead()\"\r\n >\r\n <mt-icon icon=\"general.check\"></mt-icon>\r\n\r\n <span>Mark read</span>\r\n </button>\r\n\r\n @if (showParticipants()) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100\"\r\n (click)=\"actionsPopover.hide(); toggleParticipantsPanel()\"\r\n >\r\n <mt-icon icon=\"user.users-01\"></mt-icon>\r\n\r\n <span>{{\r\n participantsExpanded()\r\n ? \"Hide participants\"\r\n : \"Show participants\"\r\n }}</span>\r\n </button>\r\n }\r\n </div>\r\n </p-popover>\r\n </div>\r\n </header>\r\n\r\n @if (showParticipants() && participantsExpanded()) {\r\n <section class=\"border-b border-surface-200 px-4 py-3\">\r\n @if (participantsLoading()) {\r\n <span class=\"text-xs text-surface-500\">Loading participants...</span>\r\n } @else if (participantEntities().length === 0) {\r\n <span class=\"text-xs text-surface-500\">No participants yet.</span>\r\n } @else {\r\n <div class=\"max-h-48 overflow-y-auto pr-1\">\r\n <mt-entities-preview [entities]=\"participantEntities()\" />\r\n </div>\r\n }\r\n </section>\r\n }\r\n\r\n @if (errorMessage(); as error) {\r\n <div\r\n class=\"border-b border-red-200 bg-red-50 px-4 py-2 text-sm text-red-700\"\r\n >\r\n {{ error }}\r\n </div>\r\n }\r\n\r\n <div class=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\r\n <div\r\n #viewport\r\n class=\"min-h-0 flex-1 space-y-3 overflow-x-hidden overflow-y-auto overscroll-contain bg-surface-50/60 px-3 py-3\"\r\n (scroll)=\"onViewportScroll()\"\r\n >\r\n @if (hasMore()) {\r\n <div class=\"flex justify-center py-1\">\r\n <mt-button\r\n icon=\"arrow.chevron-up\"\r\n [label]=\"loadingMore() ? 'Loading...' : 'Load older messages'\"\r\n size=\"small\"\r\n [outlined]=\"true\"\r\n [loading]=\"loadingMore()\"\r\n (onClick)=\"loadOlder()\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (loadingInitial()) {\r\n <div class=\"space-y-2\">\r\n @for (item of [1, 2, 3, 4]; track item) {\r\n <div class=\"h-16 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (commentsAsc().length === 0) {\r\n <div class=\"rounded-2xl p-8 text-center\">\r\n <h4 class=\"text-sm font-semibold text-surface-700\">\r\n No comments yet\r\n </h4>\r\n <p class=\"mt-1 text-xs text-surface-500\">Start the conversation.</p>\r\n </div>\r\n } @else {\r\n @for (comment of commentsAsc(); track trackComment($index, comment)) {\r\n @if (firstUnreadCommentId() === comment.id) {\r\n <div class=\"my-1 flex items-center justify-center gap-2\">\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n <span\r\n class=\"rounded-full border border-red-200 bg-red-50 px-2 py-0.5 text-[0.67rem] font-bold leading-none text-red-700\"\r\n >Unread messages</span\r\n >\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n </div>\r\n }\r\n\r\n <article\r\n class=\"group flex gap-2\"\r\n [class.justify-end]=\"isOwnComment(comment)\"\r\n >\r\n @if (!isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"w-fit min-w-0 max-w-full rounded-[1.35rem] border border-surface-200 bg-white px-3 py-2.5 sm:max-w-[90%]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_7%,white)]]=\"\r\n isOwnComment(comment)\r\n \"\r\n >\r\n <div\r\n class=\"mb-1 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <div\r\n class=\"text-xs w-full text-surface-600 flex justify-between\"\r\n >\r\n <div class=\"font-semibold text-surface-900\">\r\n {{ comment.createdBy }}\r\n </div>\r\n <div>\r\n <span>{{\r\n comment.createdAt | date: \"MMM d, y h:mm a\"\r\n }}</span>\r\n @if (comment.updatedAt) {\r\n <span class=\"ml-1 text-[11px] text-surface-500\"\r\n >(edited)</span\r\n >\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (getParentComment(comment); as parentComment) {\r\n <button\r\n type=\"button\"\r\n class=\"mb-2 block w-full rounded-xl border border-surface-200 bg-surface-50 px-2 py-1 text-left text-xs text-surface-600\"\r\n (click)=\"openReply(parentComment)\"\r\n >\r\n <span class=\"font-semibold\">{{\r\n parentComment.createdBy\r\n }}</span>\r\n <span class=\"mx-1\">:</span>\r\n <span class=\"line-clamp-1\">{{\r\n parentComment.comment\r\n }}</span>\r\n </button>\r\n }\r\n\r\n @if (editingCommentId() === comment.id) {\r\n <div class=\"relative\">\r\n <textarea\r\n rows=\"3\"\r\n class=\"w-full min-h-[5.25rem] resize-y rounded-2xl border border-surface-300 bg-white px-3 py-2.5 text-[0.86rem] leading-[1.45] text-surface-900 outline-none focus-visible:outline-2 focus-visible:outline-[color-mix(in_srgb,var(--p-primary-color)_32%,transparent)] focus-visible:outline-offset-1\"\r\n [ngModel]=\"editText()\"\r\n (ngModelChange)=\"editText.set($event)\"\r\n (input)=\"onEditInput($event)\"\r\n (keyup)=\"onEditCaretEvent($event)\"\r\n (click)=\"onEditCaretEvent($event)\"\r\n (scroll)=\"onEditCaretEvent($event)\"\r\n (keydown)=\"onEditKeydown($event)\"\r\n ></textarea>\r\n\r\n @if (\r\n mentionSession()?.mode === \"edit\" &&\r\n mentionSession()?.editCommentId === comment.id\r\n ) {\r\n <div\r\n class=\"absolute top-0 left-0 z-20 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span\r\n class=\"flex min-w-0 flex-1 flex-col gap-0.5\"\r\n >\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"mt-2 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <span class=\"text-xs text-surface-500\"\r\n >{{ editText().length }}/10000</span\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-surface-300 bg-transparent px-3 py-2 text-xs font-semibold leading-none text-surface-700 transition-colors hover:border-[color-mix(in_srgb,var(--p-primary-color)_24%,transparent)] hover:bg-[color-mix(in_srgb,var(--p-primary-color)_8%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"cancelEdit()\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-[color-mix(in_srgb,var(--p-primary-color)_26%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_12%,white)] px-3 py-2 text-xs font-bold leading-none text-[color-mix(in_srgb,var(--p-primary-color)_76%,black)] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_17%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"!canSaveEdit()\"\r\n (click)=\"saveEdit()\"\r\n >\r\n {{ savingEdit() ? \"Saving...\" : \"Save\" }}\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"whitespace-pre-wrap pt-1 break-words text-sm leading-6\"\r\n >\r\n @for (\r\n segment of getCommentSegments(comment);\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n [attr.data-user-id]=\"segment.userId || null\"\r\n >\r\n {{ segment.text }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (comment.attachments.length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2\">\r\n @for (\r\n attachment of comment.attachments;\r\n track attachment.id\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex max-w-full items-center gap-1.5 rounded-lg border border-surface-300 px-2 py-1 text-[0.72rem] hover:bg-surface-50\"\r\n (click)=\"downloadAttachment(comment, attachment)\"\r\n >\r\n <span class=\"truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n <span class=\"text-[11px] text-surface-500\"\r\n >({{ attachment.size | number }} bytes)</span\r\n >\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"mt-2 flex flex-wrap items-center gap-1\">\r\n @if (!comment.isSystem) {\r\n <button\r\n type=\"button\"\r\n class=\"cursor-pointer rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openReply(comment)\"\r\n >\r\n Reply\r\n </button>\r\n }\r\n @if (canEditComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"startEdit(comment)\"\r\n >\r\n Edit\r\n </button>\r\n }\r\n @if (canDeleteComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-red-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"isDeleting(comment.id)\"\r\n (click)=\"deleteComment(comment)\"\r\n >\r\n {{ isDeleting(comment.id) ? \"Deleting...\" : \"Delete\" }}\r\n </button>\r\n }\r\n @if (comment.updatedAt) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openRevisions(comment)\"\r\n >\r\n History\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n </article>\r\n }\r\n }\r\n </div>\r\n\r\n <footer\r\n class=\"z-10 shrink-0 border-t border-surface-200 bg-content px-3 py-3\"\r\n >\r\n @if (replyToComment(); as replyComment) {\r\n <div\r\n class=\"mb-2 flex items-center justify-between rounded-xl border border-surface-200 bg-surface-50 px-2 py-1\"\r\n >\r\n <div class=\"min-w-0 text-xs text-surface-600\">\r\n <span class=\"font-semibold\"\r\n >Replying to {{ replyComment.createdBy }}</span\r\n >\r\n <p class=\"truncate\">{{ replyComment.comment }}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"clearReply()\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"rounded-[1.5rem] border border-surface-300 bg-white p-2.5 shadow-sm\"\r\n >\r\n <div class=\"relative\">\r\n <textarea\r\n #composerInput\r\n rows=\"2\"\r\n class=\"w-full min-h-[3.75rem] resize-none border-0 bg-transparent px-2 pb-10 pr-24 pt-1 text-[0.9rem] leading-[1.45] text-surface-900 outline-none\"\r\n [disabled]=\"disabled() || posting()\"\r\n [ngModel]=\"composerText()\"\r\n (ngModelChange)=\"composerText.set($event)\"\r\n (input)=\"onComposerInput($event)\"\r\n (keyup)=\"onComposerCaretEvent($event)\"\r\n (click)=\"onComposerCaretEvent($event)\"\r\n (scroll)=\"onComposerCaretEvent($event)\"\r\n (keydown)=\"onComposerKeydown($event)\"\r\n [placeholder]=\"placeholder()\"\r\n ></textarea>\r\n\r\n <div class=\"absolute right-1 bottom-1 flex items-center gap-2\">\r\n @if (allowAttachments()) {\r\n <mt-button\r\n icon=\"file.paperclip\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [disabled]=\"disabled() || posting()\"\r\n (onClick)=\"browseAttachments()\"\r\n />\r\n }\r\n\r\n <mt-button\r\n icon=\"communication.send-01\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-send-btn\"\r\n [loading]=\"posting()\"\r\n [disabled]=\"!canSend()\"\r\n (onClick)=\"sendComment()\"\r\n />\r\n </div>\r\n\r\n @if (mentionSession()?.mode === \"composer\") {\r\n <div\r\n class=\"absolute top-0 left-0 z-30 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (composerAttachments().length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2 px-1\">\r\n @for (attachment of composerAttachments(); track attachment.id) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-2.5 py-1.5 text-xs\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"max-w-[12rem] truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n @if (attachment.status === \"uploading\") {\r\n <span class=\"text-surface-500\"\r\n >{{ attachment.progress }}%</span\r\n >\r\n } @else if (attachment.status === \"failed\") {\r\n <span class=\"text-red-600\">Failed</span>\r\n } @else {\r\n <span class=\"text-emerald-600\">Ready</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"removeAttachment(attachment.id)\"\r\n >\r\n Remove\r\n </button>\r\n </div>\r\n @if (attachment.error) {\r\n <p class=\"text-[11px] text-red-600\">\r\n {{ attachment.error }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (composerText().length > 10000) {\r\n <div class=\"mt-2 px-1 text-xs font-medium text-red-600\">\r\n Comment cannot exceed 10000 characters.\r\n </div>\r\n }\r\n </div>\r\n </footer>\r\n </div>\r\n </div>\r\n</mt-card>\r\n\r\n<p-dialog\r\n [visible]=\"revisionsDialogVisible()\"\r\n (visibleChange)=\"revisionsDialogVisible.set($event)\"\r\n [modal]=\"true\"\r\n [dismissableMask]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: 'min(42rem, 92vw)' }\"\r\n header=\"Comment history\"\r\n>\r\n @if (revisionLoading()) {\r\n <div class=\"space-y-2\">\r\n @for (row of [1, 2, 3]; track row) {\r\n <div class=\"h-12 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (visibleRevisions().length === 0) {\r\n <p class=\"text-sm text-surface-500\">No revision snapshots.</p>\r\n } @else {\r\n <div class=\"max-h-[55vh] space-y-2 overflow-y-auto pr-1\">\r\n @for (revision of visibleRevisions(); track revision.id) {\r\n <article class=\"rounded-xl border border-surface-200 p-3\">\r\n <div class=\"mb-1 text-xs text-surface-500\">\r\n Revision #{{ revision.revisionNumber }} •\r\n {{ revision.createdAt | date: \"MMM d, y h:mm a\" }} •\r\n {{ revision.createdBy }}\r\n </div>\r\n <div class=\"whitespace-pre-wrap break-words text-sm leading-6\">\r\n @for (\r\n segment of getCommentSegments({\r\n id: revision.id,\r\n moduleType: selectedRevisionComment()?.moduleType || \"\",\r\n recordId: selectedRevisionComment()?.recordId || 0,\r\n parentCommentId: null,\r\n comment: revision.comment,\r\n isSystem: false,\r\n createdAt: revision.createdAt,\r\n updatedAt: null,\r\n createdBy: revision.createdBy,\r\n updatedBy: null,\r\n attachments: [],\r\n mentions: revision.mentions,\r\n });\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n >{{ segment.text }}</span\r\n >\r\n }\r\n </div>\r\n </article>\r\n }\r\n </div>\r\n }\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div{display:flex;flex-direction:column;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div>div.flex-1{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}:host ::ng-deep .mt-discussion-actions-popover .p-popover-content{padding:.25rem}:host ::ng-deep .mt-discussion-icon-btn,:host ::ng-deep .mt-discussion-send-btn{height:2.25rem;width:2.25rem;min-width:2.25rem}:host ::ng-deep .mt-discussion-send-btn{box-shadow:0 10px 24px color-mix(in srgb,var(--p-primary-color) 22%,transparent)}\n"] }]
|
|
1637
|
+
}, template: "<mt-card\r\n class=\"mt-discussion-card h-full min-h-0 w-full overflow-hidden shadow-sm\"\r\n [paddingless]=\"true\"\r\n [ngClass]=\"styleClass()\"\r\n>\r\n <div class=\"flex h-full min-h-0 flex-col overflow-hidden\">\r\n <input\r\n #attachmentInput\r\n type=\"file\"\r\n class=\"hidden\"\r\n multiple\r\n (change)=\"onAttachmentSelected($event)\"\r\n />\r\n\r\n <header\r\n class=\"flex items-center justify-between gap-3 border-b border-surface-200 bg-surface-0 px-4 py-3.5\"\r\n >\r\n <div class=\"min-w-0 flex-1 flex items-center gap-2\">\r\n <div class=\"text-2xl text-surface-500 font-semibold\">\r\n <mt-icon icon=\"communication.message-chat-square\"></mt-icon>\r\n </div>\r\n <h3 class=\"truncate text-base font-semibold text-surface-900\">\r\n {{ title() }}\r\n </h3>\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [loading]=\"refreshing()\"\r\n [disabled]=\"loadingInitial() || markingRead()\"\r\n (onClick)=\"actionsPopover.toggle($event)\"\r\n />\r\n\r\n <p-popover\r\n #actionsPopover\r\n appendTo=\"body\"\r\n styleClass=\"mt-discussion-actions-popover\"\r\n >\r\n <div class=\"flex min-w-44 flex-col py-1\">\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"refreshing() || loadingInitial()\"\r\n (click)=\"actionsPopover.hide(); refreshThread()\"\r\n >\r\n <mt-icon icon=\"arrow.refresh-cw-01\"></mt-icon>\r\n\r\n <span>{{ refreshing() ? \"Refreshing...\" : \"Refresh\" }}</span>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100 disabled:cursor-not-allowed disabled:opacity-50\"\r\n [disabled]=\"markingRead() || !hasUnread()\"\r\n (click)=\"actionsPopover.hide(); markRead()\"\r\n >\r\n <mt-icon icon=\"general.check\"></mt-icon>\r\n\r\n <span>Mark read</span>\r\n </button>\r\n\r\n @if (showParticipants()) {\r\n <button\r\n type=\"button\"\r\n class=\"flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left text-sm text-surface-700 transition-colors hover:bg-surface-100\"\r\n (click)=\"actionsPopover.hide(); toggleParticipantsPanel()\"\r\n >\r\n <mt-icon icon=\"user.users-01\"></mt-icon>\r\n\r\n <span>{{\r\n participantsExpanded()\r\n ? \"Hide participants\"\r\n : \"Show participants\"\r\n }}</span>\r\n </button>\r\n }\r\n </div>\r\n </p-popover>\r\n </div>\r\n </header>\r\n\r\n @if (showParticipants() && participantsExpanded()) {\r\n <section class=\"border-b border-surface-200 px-4 py-3\">\r\n @if (participantsLoading()) {\r\n <span class=\"text-xs text-surface-500\">Loading participants...</span>\r\n } @else if (participantEntities().length === 0) {\r\n <span class=\"text-xs text-surface-500\">No participants yet.</span>\r\n } @else {\r\n <div class=\"max-h-48 overflow-y-auto pr-1\">\r\n <mt-entities-preview [entities]=\"participantEntities()\" />\r\n </div>\r\n }\r\n </section>\r\n }\r\n\r\n @if (errorMessage(); as error) {\r\n <div\r\n class=\"border-b border-red-200 bg-red-50 px-4 py-2 text-sm text-red-700\"\r\n >\r\n {{ error }}\r\n </div>\r\n }\r\n\r\n <div class=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\r\n <div\r\n #viewport\r\n class=\"min-h-0 flex-1 space-y-3 overflow-x-hidden overflow-y-auto overscroll-contain bg-surface-50/60 px-3 py-3\"\r\n (scroll)=\"onViewportScroll()\"\r\n >\r\n @if (hasMore()) {\r\n <div class=\"flex justify-center py-1\">\r\n <mt-button\r\n icon=\"arrow.chevron-up\"\r\n [label]=\"loadingMore() ? 'Loading...' : 'Load older messages'\"\r\n size=\"small\"\r\n [outlined]=\"true\"\r\n [loading]=\"loadingMore()\"\r\n (onClick)=\"loadOlder()\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (loadingInitial()) {\r\n <div class=\"space-y-2\">\r\n @for (item of [1, 2, 3, 4]; track item) {\r\n <div class=\"h-16 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (commentsAsc().length === 0) {\r\n <div class=\"rounded-2xl p-8 text-center\">\r\n <h4 class=\"text-sm font-semibold text-surface-700\">\r\n No comments yet\r\n </h4>\r\n <p class=\"mt-1 text-xs text-surface-500\">Start the conversation.</p>\r\n </div>\r\n } @else {\r\n @for (comment of commentsAsc(); track trackComment($index, comment)) {\r\n @if (firstUnreadCommentId() === comment.id) {\r\n <div class=\"my-1 flex items-center justify-center gap-2\">\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n <span\r\n class=\"rounded-full border border-red-200 bg-red-50 px-2 py-0.5 text-[0.67rem] font-bold leading-none text-red-700\"\r\n >Unread messages</span\r\n >\r\n <span\r\n class=\"flex-1 border-t border-dashed border-red-300\"\r\n ></span>\r\n </div>\r\n }\r\n\r\n <article\r\n class=\"group flex gap-2\"\r\n [class.justify-end]=\"isOwnComment(comment)\"\r\n >\r\n @if (!isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"w-fit min-w-0 max-w-full rounded-[1.35rem] border border-surface-200 bg-white px-3 py-2.5 sm:max-w-[90%]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_7%,white)]]=\"\r\n isOwnComment(comment)\r\n \"\r\n >\r\n <div\n class=\"mb-1 flex flex-col gap-1 text-xs text-surface-600 sm:flex-row sm:items-start sm:justify-between sm:gap-3\"\n >\n <div class=\"min-w-0 break-words font-semibold text-surface-900\">\n {{ comment.createdBy }}\n </div>\n <div\n class=\"inline-flex flex-wrap items-center gap-1 text-surface-500 sm:shrink-0 sm:flex-nowrap sm:text-right\"\n >\n <span class=\"whitespace-nowrap\">{{\n comment.createdAt | date: \"MMM d, y h:mm a\"\n }}</span>\n @if (comment.updatedAt) {\n <span class=\"whitespace-nowrap text-[11px] text-surface-500\"\n >(edited)</span\n >\n }\n </div>\n </div>\n\r\n @if (getParentComment(comment); as parentComment) {\r\n <button\r\n type=\"button\"\r\n class=\"mb-2 block w-full rounded-xl border border-surface-200 bg-surface-50 px-2 py-1 text-left text-xs text-surface-600\"\r\n (click)=\"openReply(parentComment)\"\r\n >\r\n <span class=\"font-semibold\">{{\r\n parentComment.createdBy\r\n }}</span>\r\n <span class=\"mx-1\">:</span>\r\n <span class=\"line-clamp-1\">{{\r\n parentComment.comment\r\n }}</span>\r\n </button>\r\n }\r\n\r\n @if (editingCommentId() === comment.id) {\r\n <div class=\"relative\">\r\n <textarea\r\n rows=\"3\"\r\n class=\"w-full min-h-[5.25rem] resize-y rounded-2xl border border-surface-300 bg-white px-3 py-2.5 text-[0.86rem] leading-[1.45] text-surface-900 outline-none focus-visible:outline-2 focus-visible:outline-[color-mix(in_srgb,var(--p-primary-color)_32%,transparent)] focus-visible:outline-offset-1\"\r\n [ngModel]=\"editText()\"\r\n (ngModelChange)=\"editText.set($event)\"\r\n (input)=\"onEditInput($event)\"\r\n (keyup)=\"onEditCaretEvent($event)\"\r\n (click)=\"onEditCaretEvent($event)\"\r\n (scroll)=\"onEditCaretEvent($event)\"\r\n (keydown)=\"onEditKeydown($event)\"\r\n ></textarea>\r\n\r\n @if (\r\n mentionSession()?.mode === \"edit\" &&\r\n mentionSession()?.editCommentId === comment.id\r\n ) {\r\n <div\r\n class=\"absolute top-0 left-0 z-20 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span\r\n class=\"flex min-w-0 flex-1 flex-col gap-0.5\"\r\n >\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"mt-2 flex flex-wrap items-center justify-between gap-2\"\r\n >\r\n <span class=\"text-xs text-surface-500\"\r\n >{{ editText().length }}/10000</span\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-surface-300 bg-transparent px-3 py-2 text-xs font-semibold leading-none text-surface-700 transition-colors hover:border-[color-mix(in_srgb,var(--p-primary-color)_24%,transparent)] hover:bg-[color-mix(in_srgb,var(--p-primary-color)_8%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"cancelEdit()\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-[0.65rem] border border-[color-mix(in_srgb,var(--p-primary-color)_26%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_12%,white)] px-3 py-2 text-xs font-bold leading-none text-[color-mix(in_srgb,var(--p-primary-color)_76%,black)] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_17%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"!canSaveEdit()\"\r\n (click)=\"saveEdit()\"\r\n >\r\n {{ savingEdit() ? \"Saving...\" : \"Save\" }}\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"whitespace-pre-wrap pt-1 break-words text-sm leading-6\"\r\n >\r\n @for (\r\n segment of getCommentSegments(comment);\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n [attr.data-user-id]=\"segment.userId || null\"\r\n >\r\n {{ segment.text }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (comment.attachments.length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2\">\r\n @for (\r\n attachment of comment.attachments;\r\n track attachment.id\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex max-w-full items-center gap-1.5 rounded-lg border border-surface-300 px-2 py-1 text-[0.72rem] hover:bg-surface-50\"\r\n (click)=\"downloadAttachment(comment, attachment)\"\r\n >\r\n <span class=\"truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n <span class=\"text-[11px] text-surface-500\"\r\n >({{ attachment.size | number }} bytes)</span\r\n >\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"mt-2 flex flex-wrap items-center gap-1\">\r\n @if (!comment.isSystem) {\r\n <button\r\n type=\"button\"\r\n class=\"cursor-pointer rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openReply(comment)\"\r\n >\r\n Reply\r\n </button>\r\n }\r\n @if (canEditComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"startEdit(comment)\"\r\n >\r\n Edit\r\n </button>\r\n }\r\n @if (canDeleteComment(comment)) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-red-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n [disabled]=\"isDeleting(comment.id)\"\r\n (click)=\"deleteComment(comment)\"\r\n >\r\n {{ isDeleting(comment.id) ? \"Deleting...\" : \"Delete\" }}\r\n </button>\r\n }\r\n @if (comment.updatedAt) {\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"openRevisions(comment)\"\r\n >\r\n History\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isOwnComment(comment)) {\r\n <div\r\n class=\"mt-0.5 inline-flex h-[1.9rem] w-[1.9rem] shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_20%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.74rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_75%,black)]\"\r\n >\r\n {{ getAvatarText(comment) }}\r\n </div>\r\n }\r\n </article>\r\n }\r\n }\r\n </div>\r\n\r\n <footer\r\n class=\"z-10 shrink-0 border-t border-surface-200 bg-content px-3 py-3\"\r\n >\r\n @if (replyToComment(); as replyComment) {\r\n <div\r\n class=\"mb-2 flex items-center justify-between rounded-xl border border-surface-200 bg-surface-50 px-2 py-1\"\r\n >\r\n <div class=\"min-w-0 text-xs text-surface-600\">\r\n <span class=\"font-semibold\"\r\n >Replying to {{ replyComment.createdBy }}</span\r\n >\r\n <p class=\"truncate\">{{ replyComment.comment }}</p>\r\n </div>\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"clearReply()\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n }\r\n\r\n <div\r\n class=\"rounded-[1.5rem] border border-surface-300 bg-white p-2.5 shadow-sm\"\r\n >\r\n <div class=\"relative\">\r\n <textarea\r\n #composerInput\r\n rows=\"2\"\r\n class=\"w-full min-h-[3.75rem] resize-none border-0 bg-transparent px-2 pb-10 pr-24 pt-1 text-[0.9rem] leading-[1.45] text-surface-900 outline-none\"\r\n [disabled]=\"disabled() || posting()\"\r\n [ngModel]=\"composerText()\"\r\n (ngModelChange)=\"composerText.set($event)\"\r\n (input)=\"onComposerInput($event)\"\r\n (keyup)=\"onComposerCaretEvent($event)\"\r\n (click)=\"onComposerCaretEvent($event)\"\r\n (scroll)=\"onComposerCaretEvent($event)\"\r\n (keydown)=\"onComposerKeydown($event)\"\r\n [placeholder]=\"placeholder()\"\r\n ></textarea>\r\n\r\n <div class=\"absolute right-1 bottom-1 flex items-center gap-2\">\r\n @if (allowAttachments()) {\r\n <mt-button\r\n icon=\"file.paperclip\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n variant=\"text\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-icon-btn\"\r\n [disabled]=\"disabled() || posting()\"\r\n (onClick)=\"browseAttachments()\"\r\n />\r\n }\r\n\r\n <mt-button\r\n icon=\"communication.send-01\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n styleClass=\"mt-discussion-send-btn\"\r\n [loading]=\"posting()\"\r\n [disabled]=\"!canSend()\"\r\n (onClick)=\"sendComment()\"\r\n />\r\n </div>\r\n\r\n @if (mentionSession()?.mode === \"composer\") {\r\n <div\r\n class=\"absolute top-0 left-0 z-30 min-w-56 overflow-auto rounded-xl border border-surface-300 bg-white shadow-sm\"\r\n [ngStyle]=\"mentionMenuStyle()\"\r\n [class.origin-bottom-left]=\"\r\n mentionMenuPosition()?.placement === 'above'\r\n \"\r\n >\r\n @if (mentionLoading()) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n Searching...\r\n </div>\r\n } @else if (mentionCandidates().length === 0) {\r\n <div class=\"px-3 py-2 text-xs text-surface-500\">\r\n No matches\r\n </div>\r\n } @else {\r\n @for (\r\n candidate of mentionCandidates();\r\n track candidate.userId;\r\n let i = $index\r\n ) {\r\n <button\r\n type=\"button\"\r\n class=\"flex w-full cursor-pointer items-start gap-2 bg-transparent px-2.5 py-2 text-left text-[0.78rem] transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]\"\r\n [class.bg-[color-mix(in_srgb,var(--p-primary-color)_11%,white)]]=\"\r\n mentionActiveIndex() === i\r\n \"\r\n (click)=\"selectMention(candidate)\"\r\n >\r\n <span\r\n class=\"mt-px inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--p-primary-color)_18%,transparent)] bg-[color-mix(in_srgb,var(--p-primary-color)_16%,white)] text-[0.7rem] font-bold text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)]\"\r\n >\r\n {{ getMentionAvatarText(candidate) }}\r\n </span>\r\n <span class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\r\n <span\r\n class=\"text-[0.79rem] leading-[1.25] font-semibold text-surface-900\"\r\n >{{\r\n candidate.displayName ||\r\n candidate.userName ||\r\n candidate.userId\r\n }}</span\r\n >\r\n <span\r\n class=\"inline-flex items-center text-[0.73rem] leading-[1.2] text-surface-500\"\r\n >\r\n @{{ candidate.userId }}\r\n </span>\r\n </span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (composerAttachments().length > 0) {\r\n <div class=\"mt-2 flex flex-wrap gap-2 px-1\">\r\n @for (attachment of composerAttachments(); track attachment.id) {\r\n <div\r\n class=\"rounded-xl border border-surface-200 bg-surface-50 px-2.5 py-1.5 text-xs\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"max-w-[12rem] truncate\">{{\r\n attachment.fileName\r\n }}</span>\r\n @if (attachment.status === \"uploading\") {\r\n <span class=\"text-surface-500\"\r\n >{{ attachment.progress }}%</span\r\n >\r\n } @else if (attachment.status === \"failed\") {\r\n <span class=\"text-red-600\">Failed</span>\r\n } @else {\r\n <span class=\"text-emerald-600\">Ready</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"rounded-lg bg-transparent px-2 py-1 text-[0.72rem] font-semibold leading-none text-surface-600 transition-colors hover:bg-[color-mix(in_srgb,var(--p-primary-color)_10%,white)] hover:text-[color-mix(in_srgb,var(--p-primary-color)_74%,black)] disabled:cursor-not-allowed disabled:opacity-55\"\r\n (click)=\"removeAttachment(attachment.id)\"\r\n >\r\n Remove\r\n </button>\r\n </div>\r\n @if (attachment.error) {\r\n <p class=\"text-[11px] text-red-600\">\r\n {{ attachment.error }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (composerText().length > 10000) {\r\n <div class=\"mt-2 px-1 text-xs font-medium text-red-600\">\r\n Comment cannot exceed 10000 characters.\r\n </div>\r\n }\r\n </div>\r\n </footer>\r\n </div>\r\n </div>\r\n</mt-card>\r\n\r\n<p-dialog\r\n [visible]=\"revisionsDialogVisible()\"\r\n (visibleChange)=\"revisionsDialogVisible.set($event)\"\r\n [modal]=\"true\"\r\n [dismissableMask]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: 'min(42rem, 92vw)' }\"\r\n header=\"Comment history\"\r\n>\r\n @if (revisionLoading()) {\r\n <div class=\"space-y-2\">\r\n @for (row of [1, 2, 3]; track row) {\r\n <div class=\"h-12 animate-pulse rounded-xl bg-surface-100\"></div>\r\n }\r\n </div>\r\n } @else if (visibleRevisions().length === 0) {\r\n <p class=\"text-sm text-surface-500\">No revision snapshots.</p>\r\n } @else {\r\n <div class=\"max-h-[55vh] space-y-2 overflow-y-auto pr-1\">\r\n @for (revision of visibleRevisions(); track revision.id) {\r\n <article class=\"rounded-xl border border-surface-200 p-3\">\r\n <div class=\"mb-1 text-xs text-surface-500\">\r\n Revision #{{ revision.revisionNumber }} •\r\n {{ revision.createdAt | date: \"MMM d, y h:mm a\" }} •\r\n {{ revision.createdBy }}\r\n </div>\r\n <div class=\"whitespace-pre-wrap break-words text-sm leading-6\">\r\n @for (\r\n segment of getCommentSegments({\r\n id: revision.id,\r\n moduleType: selectedRevisionComment()?.moduleType || \"\",\r\n recordId: selectedRevisionComment()?.recordId || 0,\r\n parentCommentId: null,\r\n comment: revision.comment,\r\n isSystem: false,\r\n createdAt: revision.createdAt,\r\n updatedAt: null,\r\n createdBy: revision.createdBy,\r\n updatedBy: null,\r\n attachments: [],\r\n mentions: revision.mentions,\r\n });\r\n track $index\r\n ) {\r\n <span\r\n [ngClass]=\"\r\n segment.isMention\r\n ? 'rounded-sm bg-primary-50 px-0.5 font-semibold text-primary-700'\r\n : ''\r\n \"\r\n >{{ segment.text }}</span\r\n >\r\n }\r\n </div>\r\n </article>\r\n }\r\n </div>\r\n }\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div{display:flex;flex-direction:column;height:100%;min-height:0;min-width:0}:host ::ng-deep .mt-discussion-card>div>div.flex-1{display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}:host ::ng-deep .mt-discussion-actions-popover .p-popover-content{padding:.25rem}:host ::ng-deep .mt-discussion-icon-btn,:host ::ng-deep .mt-discussion-send-btn{height:2.25rem;width:2.25rem;min-width:2.25rem}:host ::ng-deep .mt-discussion-send-btn{box-shadow:0 10px 24px color-mix(in srgb,var(--p-primary-color) 22%,transparent)}\n"] }]
|
|
1638
1638
|
}], ctorParameters: () => [], propDecorators: { moduleType: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleType", required: true }] }], recordId: [{ type: i0.Input, args: [{ isSignal: true, alias: "recordId", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], currentUserId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentUserId", required: false }] }], requestContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestContext", required: false }] }], mentionableUsers: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionableUsers", required: false }] }], mentionSearchEndpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionSearchEndpoint", required: false }] }], mentionSearchParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionSearchParam", required: false }] }], mentionSearchDataPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "mentionSearchDataPath", required: false }] }], allowAttachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAttachments", required: false }] }], uploadEndpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadEndpoint", required: false }] }], attachmentDownloadEndpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentDownloadEndpoint", required: false }] }], showParticipants: [{ type: i0.Input, args: [{ isSignal: true, alias: "showParticipants", required: false }] }], autoMarkRead: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoMarkRead", required: false }] }], refreshIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshIntervalMs", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loaded: [{ type: i0.Output, args: ["loaded"] }], errored: [{ type: i0.Output, args: ["errored"] }], commentCreated: [{ type: i0.Output, args: ["commentCreated"] }], commentUpdated: [{ type: i0.Output, args: ["commentUpdated"] }], commentDeleted: [{ type: i0.Output, args: ["commentDeleted"] }], readStateChanged: [{ type: i0.Output, args: ["readStateChanged"] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], composerInputRef: [{ type: i0.ViewChild, args: ['composerInput', { isSignal: true }] }], attachmentInputRef: [{ type: i0.ViewChild, args: ['attachmentInput', { isSignal: true }] }] } });
|
|
1639
1639
|
|
|
1640
1640
|
/**
|