@joewinke/jatui 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CLAUDE.md +244 -0
  2. package/package.json +23 -10
  3. package/src/lib/actions/collapse.ts +0 -134
  4. package/src/lib/actions/railNav.ts +0 -473
  5. package/src/lib/components/AnnotationLayer.svelte +0 -108
  6. package/src/lib/components/AnnotationPanel.svelte +0 -319
  7. package/src/lib/components/AudioWaveform.svelte +0 -698
  8. package/src/lib/components/AvailabilityModal.svelte +0 -177
  9. package/src/lib/components/AvatarUpload.svelte +0 -234
  10. package/src/lib/components/Badge.svelte +0 -38
  11. package/src/lib/components/BookingForm.svelte +0 -278
  12. package/src/lib/components/BurndownChart.svelte +0 -778
  13. package/src/lib/components/Button.svelte +0 -81
  14. package/src/lib/components/CalendarPicker.svelte +0 -284
  15. package/src/lib/components/Card.svelte +0 -67
  16. package/src/lib/components/CharacterCounter.svelte +0 -82
  17. package/src/lib/components/ChipInput.svelte +0 -609
  18. package/src/lib/components/Collapse.svelte +0 -82
  19. package/src/lib/components/ColorSelector.svelte +0 -167
  20. package/src/lib/components/CommentThread.svelte +0 -773
  21. package/src/lib/components/ConfirmDialog.svelte +0 -348
  22. package/src/lib/components/ConfirmModal.svelte +0 -142
  23. package/src/lib/components/ContextMenu.svelte +0 -188
  24. package/src/lib/components/CountdownTimer.svelte +0 -94
  25. package/src/lib/components/DateRangePicker.svelte +0 -194
  26. package/src/lib/components/Drawer.svelte +0 -143
  27. package/src/lib/components/EmojiPicker.svelte +0 -159
  28. package/src/lib/components/EntityPreviewCard.svelte +0 -104
  29. package/src/lib/components/FileDropzone.svelte +0 -493
  30. package/src/lib/components/FilePicker.svelte +0 -488
  31. package/src/lib/components/FileThumbnail.svelte +0 -80
  32. package/src/lib/components/FilterDropdown.svelte +0 -203
  33. package/src/lib/components/FloatingActionBar.svelte +0 -354
  34. package/src/lib/components/GPSTracker.svelte +0 -202
  35. package/src/lib/components/HunkDiffView.svelte +0 -348
  36. package/src/lib/components/ImageLightbox.svelte +0 -274
  37. package/src/lib/components/ImageUpload.svelte +0 -147
  38. package/src/lib/components/InlineEdit.svelte +0 -291
  39. package/src/lib/components/InputDialog.svelte +0 -327
  40. package/src/lib/components/KeyboardShortcutsOverlay.svelte +0 -296
  41. package/src/lib/components/LazyImage.svelte +0 -123
  42. package/src/lib/components/LinkShortener.svelte +0 -274
  43. package/src/lib/components/LoadingSpinner.svelte +0 -106
  44. package/src/lib/components/LocationMap.svelte +0 -186
  45. package/src/lib/components/MapView.svelte +0 -341
  46. package/src/lib/components/MarkupEditor.svelte +0 -485
  47. package/src/lib/components/MarkupOverlay.svelte +0 -55
  48. package/src/lib/components/MediaWorkbench.svelte +0 -871
  49. package/src/lib/components/MilestoneCard.svelte +0 -98
  50. package/src/lib/components/MilestoneTimeline.svelte +0 -91
  51. package/src/lib/components/Modal.svelte +0 -244
  52. package/src/lib/components/PDFViewer.svelte +0 -105
  53. package/src/lib/components/PdfThumbnail.svelte +0 -63
  54. package/src/lib/components/PhoneInput.svelte +0 -212
  55. package/src/lib/components/ResizableDivider.svelte +0 -307
  56. package/src/lib/components/ResizablePanel.svelte +0 -305
  57. package/src/lib/components/SearchDropdown.svelte +0 -421
  58. package/src/lib/components/SelectInput.svelte +0 -237
  59. package/src/lib/components/SidebarUserFooter.svelte +0 -34
  60. package/src/lib/components/SignaturePad.svelte +0 -175
  61. package/src/lib/components/SmartImageEditor.svelte +0 -720
  62. package/src/lib/components/SortDropdown.svelte +0 -156
  63. package/src/lib/components/Sparkline.svelte +0 -116
  64. package/src/lib/components/SpeechForm.svelte +0 -114
  65. package/src/lib/components/StatusBadge.svelte +0 -157
  66. package/src/lib/components/TaskTypeIcon.svelte +0 -54
  67. package/src/lib/components/TextArea.svelte +0 -162
  68. package/src/lib/components/TextInput.svelte +0 -131
  69. package/src/lib/components/ThemeSelector.svelte +0 -206
  70. package/src/lib/components/TimeSlotPicker.svelte +0 -162
  71. package/src/lib/components/UserAvatar.svelte +0 -72
  72. package/src/lib/components/VariablePicker.svelte +0 -170
  73. package/src/lib/components/VoicePlayer.svelte +0 -422
  74. package/src/lib/components/linked-columns/LinkedColumns.svelte +0 -526
  75. package/src/lib/components/markup.ts +0 -287
  76. package/src/lib/components/messaging/Avatar.svelte +0 -81
  77. package/src/lib/components/messaging/ChannelInfoModal.svelte +0 -163
  78. package/src/lib/components/messaging/ChannelList.svelte +0 -107
  79. package/src/lib/components/messaging/ChannelMemberAvatarStack.svelte +0 -69
  80. package/src/lib/components/messaging/ChannelMembersModal.svelte +0 -182
  81. package/src/lib/components/messaging/CreateChannelModal.svelte +0 -190
  82. package/src/lib/components/messaging/DirectMessageList.svelte +0 -145
  83. package/src/lib/components/messaging/EmojiSelector.svelte +0 -261
  84. package/src/lib/components/messaging/MentionAutocomplete.svelte +0 -193
  85. package/src/lib/components/messaging/MessageAttachment.svelte +0 -273
  86. package/src/lib/components/messaging/MessageAttachmentUpload.svelte +0 -243
  87. package/src/lib/components/messaging/MessageInput.svelte +0 -452
  88. package/src/lib/components/messaging/MessageItem.svelte +0 -341
  89. package/src/lib/components/messaging/MessageThread.svelte +0 -306
  90. package/src/lib/components/messaging/NotificationSettingsModal.svelte +0 -234
  91. package/src/lib/components/messaging/QuotedMessageDisplay.svelte +0 -123
  92. package/src/lib/components/messaging/StartDMModal.svelte +0 -100
  93. package/src/lib/components/messaging/ThreadPanel.svelte +0 -153
  94. package/src/lib/components/pipeline/DESIGN.md +0 -361
  95. package/src/lib/components/pipeline/Pipeline.svelte +0 -391
  96. package/src/lib/components/pipeline/PipelineCard.svelte +0 -94
  97. package/src/lib/components/pipeline/PipelineColumn.svelte +0 -163
  98. package/src/lib/components/replay/ChapterTimeline.svelte +0 -326
  99. package/src/lib/components/session-nav/transcriptModel.ts +0 -352
  100. package/src/lib/data/emojis.ts +0 -1208
  101. package/src/lib/index.ts +0 -405
  102. package/src/lib/stores/confirmDialog.svelte.ts +0 -48
  103. package/src/lib/stores/inputDialog.svelte.ts +0 -51
  104. package/src/lib/styles/rail.css +0 -63
  105. package/src/lib/types/annotation.ts +0 -38
  106. package/src/lib/types/booking.ts +0 -143
  107. package/src/lib/types/comments.ts +0 -97
  108. package/src/lib/types/entityPreview.ts +0 -45
  109. package/src/lib/types/filePicker.ts +0 -16
  110. package/src/lib/types/googleMaps.d.ts +0 -51
  111. package/src/lib/types/maps.ts +0 -43
  112. package/src/lib/types/messaging.ts +0 -459
  113. package/src/lib/types/milestone.ts +0 -22
  114. package/src/lib/types/pipeline.ts +0 -150
  115. package/src/lib/types/smartImageEditor.ts +0 -39
  116. package/src/lib/types/templateVars.ts +0 -36
  117. package/src/lib/utils/currency.ts +0 -20
  118. package/src/lib/utils/daisyuiColors.ts +0 -243
  119. package/src/lib/utils/dateFormatters.ts +0 -196
  120. package/src/lib/utils/googleMapsLoader.ts +0 -84
  121. package/src/lib/utils/mentionParser.ts +0 -188
  122. package/src/lib/utils/phone.ts +0 -80
  123. package/src/lib/utils/phoneFormat.ts +0 -74
  124. package/src/lib/utils/taskUtils.ts +0 -75
@@ -1,188 +0,0 @@
1
- /**
2
- * Mention Parser Utilities
3
- *
4
- * Handles parsing and rendering of @-mentions in messages.
5
- * Format: [@Display Name](type:id) -> clickable links
6
- *
7
- * The URL generator is configurable — consuming apps provide their own
8
- * routing via the `urlGenerator` parameter or by setting a default.
9
- */
10
-
11
- export interface MentionMatch {
12
- type: string
13
- id: string
14
- displayName: string
15
- url: string
16
- startIndex: number
17
- endIndex: number
18
- fullMatch: string
19
- }
20
-
21
- export type MentionUrlGenerator = (type: string, id: string) => string
22
-
23
- // Regex to match mention pattern: [@Display Name](type:id)
24
- const MENTION_REGEX = /\[@([^\]]+)\]\(([^:]+):([^)]+)\)/g
25
-
26
- // Default URL generator (apps can override)
27
- let defaultUrlGenerator: MentionUrlGenerator = (type, id) => `#${type}/${id}`
28
-
29
- /**
30
- * Set the default URL generator for mentions.
31
- * Call this once at app startup to configure mention link routing.
32
- */
33
- export function setMentionUrlGenerator(generator: MentionUrlGenerator): void {
34
- defaultUrlGenerator = generator
35
- }
36
-
37
- /**
38
- * Parse message content and extract all mentions
39
- */
40
- export function parseMentions(
41
- content: string,
42
- urlGenerator?: MentionUrlGenerator
43
- ): MentionMatch[] {
44
- const mentions: MentionMatch[] = []
45
- const gen = urlGenerator ?? defaultUrlGenerator
46
- let match
47
-
48
- MENTION_REGEX.lastIndex = 0
49
-
50
- while ((match = MENTION_REGEX.exec(content)) !== null) {
51
- const [fullMatch, displayName, type, id] = match
52
-
53
- mentions.push({
54
- type,
55
- id,
56
- displayName,
57
- url: gen(type, id),
58
- startIndex: match.index,
59
- endIndex: match.index + fullMatch.length,
60
- fullMatch
61
- })
62
- }
63
-
64
- return mentions
65
- }
66
-
67
- /**
68
- * Convert message content with mentions to HTML
69
- */
70
- export function renderMentionsAsHTML(
71
- content: string,
72
- urlGenerator?: MentionUrlGenerator
73
- ): string {
74
- const mentions = parseMentions(content, urlGenerator)
75
-
76
- if (mentions.length === 0) {
77
- return escapeHTML(content)
78
- }
79
-
80
- let result = ''
81
- let lastIndex = 0
82
-
83
- mentions.forEach((mention) => {
84
- result += escapeHTML(content.substring(lastIndex, mention.startIndex))
85
- result += `<a href="${mention.url}" class="mention-link mention-${mention.type}" data-mention-type="${mention.type}" data-mention-id="${mention.id}">@${escapeHTML(mention.displayName)}</a>`
86
- lastIndex = mention.endIndex
87
- })
88
-
89
- result += escapeHTML(content.substring(lastIndex))
90
- return result
91
- }
92
-
93
- /**
94
- * Create a mention string for insertion into message input
95
- */
96
- export function createMentionString(type: string, id: string, displayName: string): string {
97
- return `[@${displayName}](${type}:${id})`
98
- }
99
-
100
- /**
101
- * Extract plain text from message content (remove mention markup)
102
- */
103
- export function extractPlainText(content: string): string {
104
- MENTION_REGEX.lastIndex = 0
105
- return content.replace(MENTION_REGEX, '@$1')
106
- }
107
-
108
- /**
109
- * Check if cursor is inside a mention
110
- */
111
- export function findMentionAtCursor(content: string, cursorPosition: number): MentionMatch | null {
112
- const mentions = parseMentions(content)
113
- return (
114
- mentions.find(
115
- (mention) => cursorPosition >= mention.startIndex && cursorPosition <= mention.endIndex
116
- ) || null
117
- )
118
- }
119
-
120
- /**
121
- * Find @ symbol and following text that could be a mention being typed.
122
- * Supported symbols: @ $ # ! ~ / +
123
- */
124
- export function findPartialMention(
125
- content: string,
126
- cursorPosition: number
127
- ): { start: number; query: string } | null {
128
- const mentionSymbols = ['@', '$', '#', '!', '~', '/', '+']
129
- let symbolIndex = -1
130
-
131
- for (let i = cursorPosition - 1; i >= 0; i--) {
132
- const char = content[i]
133
-
134
- if (mentionSymbols.includes(char)) {
135
- symbolIndex = i
136
- break
137
- }
138
-
139
- if (char === ' ' || char === '\n' || char === ']' || char === ')') {
140
- break
141
- }
142
- }
143
-
144
- if (symbolIndex === -1) return null
145
-
146
- const query = content.substring(symbolIndex + 1, cursorPosition).trim()
147
-
148
- const existingMention = findMentionAtCursor(content, symbolIndex)
149
- if (existingMention) return null
150
-
151
- return { start: symbolIndex, query }
152
- }
153
-
154
- /**
155
- * Replace partial mention with complete mention string
156
- */
157
- export function replaceMentionInContent(
158
- content: string,
159
- startIndex: number,
160
- endIndex: number,
161
- mentionString: string
162
- ): { newContent: string; newCursorPosition: number } {
163
- const before = content.substring(0, startIndex)
164
- const after = content.substring(endIndex)
165
- const newContent = before + mentionString + after
166
- const newCursorPosition = startIndex + mentionString.length
167
-
168
- return { newContent, newCursorPosition }
169
- }
170
-
171
- /**
172
- * Simple HTML escape function
173
- */
174
- export function escapeHTML(text: string): string {
175
- return text
176
- .replace(/&/g, '&amp;')
177
- .replace(/</g, '&lt;')
178
- .replace(/>/g, '&gt;')
179
- .replace(/"/g, '&quot;')
180
- .replace(/'/g, '&#039;')
181
- }
182
-
183
- /**
184
- * Count mentions in content
185
- */
186
- export function countMentions(content: string): number {
187
- return parseMentions(content).length
188
- }
@@ -1,80 +0,0 @@
1
- import {
2
- parsePhoneNumberFromString,
3
- type CountryCode,
4
- getCountries,
5
- getCountryCallingCode,
6
- } from "libphonenumber-js";
7
-
8
- export const DEFAULT_COUNTRY: CountryCode = "US";
9
-
10
- export function toE164(
11
- raw: string | null | undefined,
12
- defaultCountry: CountryCode = DEFAULT_COUNTRY,
13
- ): string | null {
14
- if (!raw) return null;
15
- const trimmed = raw.trim();
16
- if (!trimmed) return null;
17
- const parsed = parsePhoneNumberFromString(trimmed, defaultCountry);
18
- if (parsed?.isValid()) return parsed.number;
19
- return null;
20
- }
21
-
22
- export function formatPhoneForDisplay(e164: string | null | undefined): string {
23
- if (!e164) return "";
24
- const parsed = parsePhoneNumberFromString(e164);
25
- if (!parsed) return e164;
26
- return parsed.country === DEFAULT_COUNTRY ? parsed.formatNational() : parsed.formatInternational();
27
- }
28
-
29
- export function isValidPhone(
30
- raw: string | null | undefined,
31
- defaultCountry: CountryCode = DEFAULT_COUNTRY,
32
- ): boolean {
33
- if (!raw) return false;
34
- const parsed = parsePhoneNumberFromString(raw.trim(), defaultCountry);
35
- return parsed?.isValid() ?? false;
36
- }
37
-
38
- export type CountryOption = {
39
- code: CountryCode;
40
- name: string;
41
- dialCode: string;
42
- flag: string;
43
- };
44
-
45
- const COUNTRY_NAMES: Record<string, string> = {
46
- US: "United States", CA: "Canada", GB: "United Kingdom", AU: "Australia", NZ: "New Zealand",
47
- IE: "Ireland", DE: "Germany", FR: "France", ES: "Spain", IT: "Italy", NL: "Netherlands",
48
- BE: "Belgium", CH: "Switzerland", AT: "Austria", SE: "Sweden", NO: "Norway", DK: "Denmark",
49
- FI: "Finland", PT: "Portugal", PL: "Poland", CZ: "Czechia", GR: "Greece", MX: "Mexico",
50
- BR: "Brazil", AR: "Argentina", CL: "Chile", CO: "Colombia", PE: "Peru", JP: "Japan",
51
- KR: "South Korea", CN: "China", HK: "Hong Kong", TW: "Taiwan", SG: "Singapore", MY: "Malaysia",
52
- TH: "Thailand", PH: "Philippines", ID: "Indonesia", VN: "Vietnam", IN: "India", PK: "Pakistan",
53
- BD: "Bangladesh", IL: "Israel", AE: "UAE", SA: "Saudi Arabia", TR: "Turkey", EG: "Egypt",
54
- ZA: "South Africa", NG: "Nigeria", KE: "Kenya", RU: "Russia", UA: "Ukraine",
55
- };
56
-
57
- function flagEmoji(code: string): string {
58
- return code
59
- .toUpperCase()
60
- .split("")
61
- .map((c) => String.fromCodePoint(127397 + c.charCodeAt(0)))
62
- .join("");
63
- }
64
-
65
- let countriesCache: CountryOption[] | null = null;
66
- export function listCountries(): CountryOption[] {
67
- if (countriesCache) return countriesCache;
68
- const all = getCountries()
69
- .map((code) => ({
70
- code,
71
- name: COUNTRY_NAMES[code] ?? code,
72
- dialCode: `+${getCountryCallingCode(code)}`,
73
- flag: flagEmoji(code),
74
- }))
75
- .sort((a, b) => a.name.localeCompare(b.name));
76
- countriesCache = all;
77
- return all;
78
- }
79
-
80
- export const PRIORITY_COUNTRIES: CountryCode[] = ["US", "CA", "GB", "AU", "MX"];
@@ -1,74 +0,0 @@
1
- /**
2
- * Phone number formatting utilities
3
- *
4
- * Provides consistent phone number formatting as (xxx) xxx-xxxx
5
- * Limits input to 10 digits and handles formatting as user types
6
- */
7
-
8
- /**
9
- * Strips all non-numeric characters from a phone number
10
- */
11
- export function stripPhoneNumber(value: string): string {
12
- return value.replace(/\D/g, '');
13
- }
14
-
15
- /**
16
- * Formats a phone number to (xxx) xxx-xxxx format
17
- */
18
- export function formatPhoneNumber(value: string): string {
19
- const digits = stripPhoneNumber(value);
20
- const limitedDigits = digits.slice(0, 10);
21
-
22
- if (limitedDigits.length === 0) {
23
- return '';
24
- } else if (limitedDigits.length <= 3) {
25
- return `(${limitedDigits}`;
26
- } else if (limitedDigits.length <= 6) {
27
- return `(${limitedDigits.slice(0, 3)}) ${limitedDigits.slice(3)}`;
28
- } else {
29
- return `(${limitedDigits.slice(0, 3)}) ${limitedDigits.slice(3, 6)}-${limitedDigits.slice(6)}`;
30
- }
31
- }
32
-
33
- /**
34
- * Checks if a phone number has exactly 10 digits
35
- */
36
- export function isCompletePhoneNumber(value: string): boolean {
37
- return stripPhoneNumber(value).length === 10;
38
- }
39
-
40
- /**
41
- * Validates phone number format (exactly 10 digits)
42
- */
43
- export function isValidPhoneNumber(value: string): boolean {
44
- return isCompletePhoneNumber(value);
45
- }
46
-
47
- /**
48
- * Handles input formatting with cursor position preservation
49
- */
50
- export function updatePhoneInput(input: HTMLInputElement, newValue: string, oldValue: string): void {
51
- const cursorPosition = input.selectionStart || 0;
52
- const oldLength = oldValue.length;
53
- const newLength = newValue.length;
54
-
55
- input.value = newValue;
56
-
57
- let newCursorPosition = cursorPosition;
58
-
59
- if (newLength > oldLength) {
60
- newCursorPosition = cursorPosition + (newLength - oldLength);
61
- } else if (newLength < oldLength) {
62
- newCursorPosition = Math.max(0, cursorPosition - (oldLength - newLength));
63
- }
64
-
65
- if (newCursorPosition === 1 && newValue.startsWith('(')) {
66
- newCursorPosition = 1;
67
- } else if (newCursorPosition === 4 && newValue.includes(') ')) {
68
- newCursorPosition = 6;
69
- } else if (newCursorPosition === 9 && newValue.includes('-')) {
70
- newCursorPosition = 10;
71
- }
72
-
73
- input.setSelectionRange(newCursorPosition, newCursorPosition);
74
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * Shared helpers for project_tasks UI.
3
- * Used across all JST-based projects on tasks/feedback pages.
4
- */
5
-
6
- /**
7
- * DaisyUI badge class for a task status value.
8
- * Usage: <span class="badge {statusColor(task.status)}">...</span>
9
- *
10
- * Aligned to the canonical JAT TASK_STATUS palette
11
- * (jat/ide/src/lib/config/statusColors.ts → TASK_STATUS_VISUALS) and the
12
- * committed JST portal palette (jst/src/lib/components/portal/portalStatus.ts
13
- * → TASK_BADGE) so a task renders the same semantics in JAT-style admin
14
- * surfaces, the JST portal, and the JAT IDE:
15
- * open=ghost(neutral) · in_progress=info(blue) · blocked=warning(amber) ·
16
- * closed=success(green). Paused / mid-flight states (waiting, review) and
17
- * post-completion states (submitted, accepted, deployed) use the outline
18
- * variants JAT applies. Where JAT and JST agree (open/in_progress/closed/
19
- * waiting), this matches both; JAT's statusColors.ts is canonical otherwise.
20
- */
21
- export function statusColor(status: string): string {
22
- switch (status) {
23
- case 'open': return 'badge-ghost';
24
- case 'in_progress': return 'badge-info';
25
- case 'waiting': return 'badge-info badge-outline';
26
- case 'review': return 'badge-info badge-outline';
27
- case 'blocked': return 'badge-warning';
28
- case 'submitted': return 'badge-secondary badge-outline';
29
- case 'accepted': return 'badge-success badge-outline';
30
- case 'deployed': return 'badge-primary badge-outline';
31
- case 'rejected': return 'badge-warning badge-outline';
32
- case 'reopened': return 'badge-warning badge-outline';
33
- case 'closed': return 'badge-success';
34
- case 'dev': return 'badge-ghost badge-outline';
35
- default: return 'badge-ghost';
36
- }
37
- }
38
-
39
- /**
40
- * Tailwind text class for a task priority value.
41
- * Usage: <span class={priorityColor(task.priority)}>...</span>
42
- */
43
- export function priorityColor(priority: string | null | undefined): string {
44
- switch (priority) {
45
- case 'critical': return 'text-error font-bold';
46
- case 'high': return 'text-warning font-semibold';
47
- case 'medium': return 'text-info';
48
- case 'low': return 'text-base-content/60';
49
- default: return '';
50
- }
51
- }
52
-
53
- /**
54
- * @deprecated Prefer the `<TaskTypeIcon type={…} />` component — it renders a
55
- * stroke SVG that inherits `currentColor`, scales precisely, and avoids
56
- * cross-OS emoji rendering drift. Kept only for backwards compatibility.
57
- * Usage: {typeIcon(task.issue_type)} {task.title}
58
- */
59
- export function typeIcon(type: string): string {
60
- switch (type) {
61
- case 'bug': return '🐛';
62
- case 'feature': return '✨';
63
- case 'task': return '📋';
64
- case 'epic': return '🏔️';
65
- default: return '📄';
66
- }
67
- }
68
-
69
- /**
70
- * Human-readable label for a task status value.
71
- * "in_progress" → "In Progress"
72
- */
73
- export function statusLabel(status: string): string {
74
- return status.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
75
- }