@qoretechnologies/reqraft 0.10.65-pr.148.gf86d88c → 0.10.65
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/.claude/CLAUDE.md +0 -1
- package/dist/components/supportTicket/InterfaceReferenceTags.d.ts +1 -13
- package/dist/components/supportTicket/InterfaceReferenceTags.d.ts.map +1 -1
- package/dist/components/supportTicket/InterfaceReferenceTags.js +4 -11
- package/dist/components/supportTicket/InterfaceReferenceTags.js.map +1 -1
- package/dist/components/supportTicket/ReferencePicker.d.ts.map +1 -1
- package/dist/components/supportTicket/ReferencePicker.js +1 -1
- package/dist/components/supportTicket/ReferencePicker.js.map +1 -1
- package/dist/components/supportTicket/index.d.ts +0 -2
- package/dist/components/supportTicket/index.d.ts.map +1 -1
- package/dist/components/supportTicket/index.js +0 -2
- package/dist/components/supportTicket/index.js.map +1 -1
- package/dist/components/supportTicket/meta.d.ts +2 -62
- package/dist/components/supportTicket/meta.d.ts.map +1 -1
- package/dist/components/supportTicket/meta.js +3 -116
- package/dist/components/supportTicket/meta.js.map +1 -1
- package/dist/components/supportTicket/ticketModel.d.ts +0 -10
- package/dist/components/supportTicket/ticketModel.d.ts.map +1 -1
- package/dist/components/ticketReferences/TicketReferences.d.ts +1 -10
- package/dist/components/ticketReferences/TicketReferences.d.ts.map +1 -1
- package/dist/components/ticketReferences/TicketReferences.js +8 -12
- package/dist/components/ticketReferences/TicketReferences.js.map +1 -1
- package/dist/components/ticketThread/TicketThread.d.ts +1 -30
- package/dist/components/ticketThread/TicketThread.d.ts.map +1 -1
- package/dist/components/ticketThread/TicketThread.js +13 -51
- package/dist/components/ticketThread/TicketThread.js.map +1 -1
- package/dist/components/ticketThread/index.d.ts +1 -1
- package/dist/components/ticketThread/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/StorageProvider.d.ts +0 -11
- package/dist/providers/StorageProvider.d.ts.map +1 -1
- package/dist/providers/StorageProvider.js +3 -21
- package/dist/providers/StorageProvider.js.map +1 -1
- package/dist/stores/currentUser/currentUser.d.ts +0 -42
- package/dist/stores/currentUser/currentUser.d.ts.map +1 -1
- package/dist/stores/currentUser/currentUser.js.map +1 -1
- package/package.json +9 -9
- package/src/components/form/engine/FormEngine.stories.tsx +5 -8
- package/src/components/form/fields/array/ArrayAutoField.stories.tsx +3 -6
- package/src/components/form/fields/boolean/Boolean.stories.tsx +3 -7
- package/src/components/form/fields/markdown/Markdown.stories.tsx +0 -6
- package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +1 -4
- package/src/components/form/fields/template/TemplateField.stories.tsx +0 -4
- package/src/components/supportTicket/InterfaceReferenceTags.stories.tsx +0 -56
- package/src/components/supportTicket/InterfaceReferenceTags.tsx +7 -27
- package/src/components/supportTicket/ReferencePicker.tsx +1 -4
- package/src/components/supportTicket/index.ts +0 -2
- package/src/components/supportTicket/meta.ts +4 -156
- package/src/components/supportTicket/ticketModel.ts +0 -10
- package/src/components/ticketReferences/TicketReferences.stories.tsx +0 -40
- package/src/components/ticketReferences/TicketReferences.tsx +10 -24
- package/src/components/ticketThread/TicketThread.stories.tsx +1 -103
- package/src/components/ticketThread/TicketThread.tsx +15 -131
- package/src/components/ticketThread/index.ts +0 -1
- package/src/index.tsx +0 -1
- package/src/providers/StorageProvider.tsx +3 -20
- package/src/stores/currentUser/currentUser.tsx +0 -43
- package/dist/components/supportTicket/WorkspaceAccessStatus.d.ts +0 -55
- package/dist/components/supportTicket/WorkspaceAccessStatus.d.ts.map +0 -1
- package/dist/components/supportTicket/WorkspaceAccessStatus.js +0 -79
- package/dist/components/supportTicket/WorkspaceAccessStatus.js.map +0 -1
- package/dist/components/supportTicket/accessMeta.d.ts +0 -50
- package/dist/components/supportTicket/accessMeta.d.ts.map +0 -1
- package/dist/components/supportTicket/accessMeta.js +0 -174
- package/dist/components/supportTicket/accessMeta.js.map +0 -1
- package/src/components/supportTicket/WorkspaceAccessStatus.stories.tsx +0 -105
- package/src/components/supportTicket/WorkspaceAccessStatus.tsx +0 -176
- package/src/components/supportTicket/accessMeta.ts +0 -210
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import { TReqoreIntent } from '@qoretechnologies/reqore/dist/constants/theme';
|
|
2
|
-
import { IReqoreIconName } from '@qoretechnologies/reqore/dist/types/icons';
|
|
3
|
-
import { ITicketEnumMeta, humaniseWireValue } from './meta';
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
* The delegated-support-access vocabulary (qorus#692): how the account's access
|
|
7
|
-
* setting, a grant's state, the reasons a grant ended, the duration presets and the
|
|
8
|
-
* grant's own audit trail read on every surface that shows them — the customer's IDE
|
|
9
|
-
* (the sign-up step, the account tab, the ticket drawer) and the staff portal (the
|
|
10
|
-
* workspace tab, the tenant card). The wire values are the SaaS plane's
|
|
11
|
-
* (`QorusSaasSupportAccessStore`, `QorusSupportSessionStore`); the words are shared so
|
|
12
|
-
* the two sides describe one grant the same way. The customer-facing LEGAL wording of
|
|
13
|
-
* the setting is not here: the plane versions and serves it with the choice.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/** The account's support access setting, least to most restrictive. */
|
|
17
|
-
export type TSupportAccessPolicy = 'auto' | 'ask' | 'never';
|
|
18
|
-
|
|
19
|
-
/** Where the governing setting came from. `default` when the customer never chose;
|
|
20
|
-
* `owner` when the workspace's billing owner's stricter setting governs the ticket. */
|
|
21
|
-
export type TSupportAccessPolicySource = 'default' | 'signup' | 'prompt' | 'settings' | 'admin' | 'owner';
|
|
22
|
-
|
|
23
|
-
export type TSupportGrantState = 'active' | 'revoked' | 'expired';
|
|
24
|
-
|
|
25
|
-
export type TSupportGrantEndCause =
|
|
26
|
-
| 'customer_revoked'
|
|
27
|
-
| 'staff_revoked'
|
|
28
|
-
| 'superseded'
|
|
29
|
-
| 'ticket_resolved'
|
|
30
|
-
| 'ticket_closed'
|
|
31
|
-
| 'policy_changed'
|
|
32
|
-
| 'account_erased'
|
|
33
|
-
| 'workspace_deleted'
|
|
34
|
-
| 'expired';
|
|
35
|
-
|
|
36
|
-
/** A duration a staff request suggests; the customer's Grant answers exactly it. */
|
|
37
|
-
export type TSupportAccessDuration = '24h' | '72h' | '7d' | 'until_resolved';
|
|
38
|
-
|
|
39
|
-
/** The grant's own audit trail (`…/access` `audit`, the account's access log). */
|
|
40
|
-
export type TSupportAccessAuditAction =
|
|
41
|
-
| 'policy_set'
|
|
42
|
-
| 'access_requested'
|
|
43
|
-
| 'granted'
|
|
44
|
-
| 'extended'
|
|
45
|
-
| 'revoked'
|
|
46
|
-
| 'expired'
|
|
47
|
-
| 'used'
|
|
48
|
-
| 'use_refused'
|
|
49
|
-
| 'session_started'
|
|
50
|
-
| 'session_ended';
|
|
51
|
-
|
|
52
|
-
/** A mark with a sentence: the setting's meaning is what a customer decides on. */
|
|
53
|
-
export interface ISupportAccessMeta extends ITicketEnumMeta {
|
|
54
|
-
description?: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** `idle_paused` → "Idle paused": a wire value as words. */
|
|
58
|
-
|
|
59
|
-
const UNKNOWN: ISupportAccessMeta = { label: 'Unknown', intent: 'muted', icon: 'QuestionLine' };
|
|
60
|
-
|
|
61
|
-
const lookup =
|
|
62
|
-
<K extends string>(table: Record<K, ISupportAccessMeta>) =>
|
|
63
|
-
(value: string | undefined): ISupportAccessMeta =>
|
|
64
|
-
value === undefined
|
|
65
|
-
? UNKNOWN
|
|
66
|
-
: ((table as Record<string, ISupportAccessMeta>)[value] ?? { ...UNKNOWN, label: humaniseWireValue(value) });
|
|
67
|
-
|
|
68
|
-
export const SUPPORT_ACCESS_POLICY_META: Record<TSupportAccessPolicy, ISupportAccessMeta> = {
|
|
69
|
-
auto: {
|
|
70
|
-
label: 'Granted automatically',
|
|
71
|
-
intent: 'success',
|
|
72
|
-
icon: 'ShieldCheckLine',
|
|
73
|
-
description: 'Read-only access for Qorus Support is granted automatically on every ticket filed.',
|
|
74
|
-
},
|
|
75
|
-
ask: {
|
|
76
|
-
label: 'Ask the customer',
|
|
77
|
-
intent: 'info',
|
|
78
|
-
icon: 'QuestionAnswerLine',
|
|
79
|
-
description: 'Support asks on each ticket; the customer decides whether to grant access.',
|
|
80
|
-
},
|
|
81
|
-
never: {
|
|
82
|
-
label: 'Never',
|
|
83
|
-
intent: 'danger',
|
|
84
|
-
icon: 'ShieldCrossLine',
|
|
85
|
-
description: 'No workspace access for Qorus Support. Support asks for information in the thread instead.',
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
/** The setting's mark; an unknown value still reads as words. */
|
|
89
|
-
export const supportAccessPolicyMeta = lookup(SUPPORT_ACCESS_POLICY_META);
|
|
90
|
-
|
|
91
|
-
export const SUPPORT_ACCESS_POLICY_SOURCE_LABEL: Record<TSupportAccessPolicySource, string> = {
|
|
92
|
-
default: 'the default, never chosen',
|
|
93
|
-
signup: 'chosen at sign-up',
|
|
94
|
-
prompt: 'chosen when first asked',
|
|
95
|
-
settings: 'chosen in the account settings',
|
|
96
|
-
admin: 'set by Qorus staff',
|
|
97
|
-
owner: "the workspace owner's stricter setting",
|
|
98
|
-
};
|
|
99
|
-
export const supportAccessPolicySourceLabel = (source: string | undefined): string =>
|
|
100
|
-
(source && (SUPPORT_ACCESS_POLICY_SOURCE_LABEL as Record<string, string>)[source]) ||
|
|
101
|
-
humaniseWireValue(source ?? '');
|
|
102
|
-
|
|
103
|
-
export const SUPPORT_GRANT_STATE_META: Record<TSupportGrantState, ISupportAccessMeta> = {
|
|
104
|
-
active: { label: 'Active', intent: 'success', icon: 'ShieldCheckLine' },
|
|
105
|
-
revoked: { label: 'Revoked', intent: 'danger', icon: 'ShieldCrossLine' },
|
|
106
|
-
expired: { label: 'Expired', intent: 'muted', icon: 'HourglassLine' },
|
|
107
|
-
};
|
|
108
|
-
export const supportGrantStateMeta = lookup(SUPPORT_GRANT_STATE_META);
|
|
109
|
-
|
|
110
|
-
export const SUPPORT_GRANT_END_CAUSE_LABEL: Record<TSupportGrantEndCause, string> = {
|
|
111
|
-
customer_revoked: 'ended by the customer',
|
|
112
|
-
staff_revoked: 'ended by support',
|
|
113
|
-
superseded: 'extended into a new grant',
|
|
114
|
-
ticket_resolved: 'the ticket was resolved',
|
|
115
|
-
ticket_closed: 'the ticket was closed',
|
|
116
|
-
policy_changed: "the account's setting changed",
|
|
117
|
-
account_erased: 'the account was erased',
|
|
118
|
-
workspace_deleted: 'the workspace was deleted',
|
|
119
|
-
expired: 'expired',
|
|
120
|
-
};
|
|
121
|
-
export const supportGrantEndCauseLabel = (cause: string | undefined): string | undefined =>
|
|
122
|
-
cause ? ((SUPPORT_GRANT_END_CAUSE_LABEL as Record<string, string>)[cause] ?? humaniseWireValue(cause)) : undefined;
|
|
123
|
-
|
|
124
|
-
export const SUPPORT_ACCESS_DURATION_LABEL: Record<TSupportAccessDuration, string> = {
|
|
125
|
-
'24h': '24 hours',
|
|
126
|
-
'72h': '3 days',
|
|
127
|
-
'7d': '7 days',
|
|
128
|
-
until_resolved: 'until the ticket is resolved',
|
|
129
|
-
};
|
|
130
|
-
export const supportAccessDurationLabel = (duration: string | undefined): string =>
|
|
131
|
-
(duration && (SUPPORT_ACCESS_DURATION_LABEL as Record<string, string>)[duration]) ||
|
|
132
|
-
humaniseWireValue(duration ?? '');
|
|
133
|
-
|
|
134
|
-
/** The grant's own trail, as a customer's access log or a staff access view lists it. */
|
|
135
|
-
export const SUPPORT_ACCESS_AUDIT_ACTION_META: Record<TSupportAccessAuditAction, ISupportAccessMeta> = {
|
|
136
|
-
policy_set: { label: 'Setting changed', intent: 'info', icon: 'Settings3Line' },
|
|
137
|
-
access_requested: { label: 'Access requested', intent: 'pending', icon: 'ShieldUserLine' },
|
|
138
|
-
granted: { label: 'Access granted', intent: 'success', icon: 'ShieldCheckLine' },
|
|
139
|
-
extended: { label: 'Access extended', intent: 'info', icon: 'TimerLine' },
|
|
140
|
-
revoked: { label: 'Access revoked', intent: 'danger', icon: 'ShieldCrossLine' },
|
|
141
|
-
expired: { label: 'Access expired', intent: 'muted', icon: 'HourglassLine' },
|
|
142
|
-
used: { label: 'Workspace read', intent: 'info', icon: 'EyeLine' },
|
|
143
|
-
use_refused: { label: 'Read refused', intent: 'warning', icon: 'ForbidLine' },
|
|
144
|
-
session_started: { label: 'IDE session started', intent: 'info', icon: 'ExternalLinkLine' },
|
|
145
|
-
session_ended: { label: 'IDE session ended', intent: 'muted', icon: 'LogoutBoxLine' },
|
|
146
|
-
};
|
|
147
|
-
/** An action the plane writes that this vocabulary has not caught up with still renders. */
|
|
148
|
-
export const supportAccessAuditActionMeta = (action: string): ISupportAccessMeta =>
|
|
149
|
-
(SUPPORT_ACCESS_AUDIT_ACTION_META as Record<string, ISupportAccessMeta>)[action] ?? {
|
|
150
|
-
...UNKNOWN,
|
|
151
|
-
icon: 'HistoryLine' as IReqoreIconName,
|
|
152
|
-
label: humaniseWireValue(action),
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
/* ── time, against a clock the caller owns ───────────────────────────────────── */
|
|
156
|
-
|
|
157
|
-
const RELATIVE_UNITS: [Intl.RelativeTimeFormatUnit, number][] = [
|
|
158
|
-
['year', 60 * 60 * 24 * 365],
|
|
159
|
-
['month', 60 * 60 * 24 * 30],
|
|
160
|
-
['week', 60 * 60 * 24 * 7],
|
|
161
|
-
['day', 60 * 60 * 24],
|
|
162
|
-
['hour', 60 * 60],
|
|
163
|
-
['minute', 60],
|
|
164
|
-
['second', 1],
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* "in 3 hours" / "2 days ago" against a clock the caller passes, so a story freezes it
|
|
169
|
-
* and two surfaces reading the same grant agree. An unparsable instant is an empty
|
|
170
|
-
* string, never "NaN years ago".
|
|
171
|
-
*
|
|
172
|
-
* Not `epoch-timeago` (what `ReqoreTimeAgo` and `TicketReferences` use): it speaks only
|
|
173
|
-
* of the past and reads the real clock, so it can neither say "in 3 hours" for a grant
|
|
174
|
-
* that is still running nor hold still in a story.
|
|
175
|
-
*/
|
|
176
|
-
export const formatRelativeTime = (iso: string | undefined, now: number, locale = 'en'): string => {
|
|
177
|
-
if (!iso) return '';
|
|
178
|
-
const then = new Date(iso).getTime();
|
|
179
|
-
if (Number.isNaN(then)) return '';
|
|
180
|
-
const seconds = Math.round((then - now) / 1000);
|
|
181
|
-
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
|
|
182
|
-
for (const [unit, secondsInUnit] of RELATIVE_UNITS) {
|
|
183
|
-
if (Math.abs(seconds) >= secondsInUnit || unit === 'second') {
|
|
184
|
-
return rtf.format(Math.round(seconds / secondsInUnit), unit);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return '';
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/** The absolute instant, for a tooltip beside a relative one. */
|
|
191
|
-
export const formatInstant = (iso: string | undefined, locale = 'en-GB'): string => {
|
|
192
|
-
if (!iso) return '';
|
|
193
|
-
const date = new Date(iso);
|
|
194
|
-
return Number.isNaN(date.getTime())
|
|
195
|
-
? iso
|
|
196
|
-
: date.toLocaleString(locale, { dateStyle: 'medium', timeStyle: 'short' });
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/** Milliseconds until an instant; negative once it passed; NaN for nothing. */
|
|
200
|
-
export const millisUntil = (iso: string | undefined, now: number): number =>
|
|
201
|
-
iso ? new Date(iso).getTime() - now : Number.NaN;
|
|
202
|
-
|
|
203
|
-
/** The intent a grant's remaining time reads as: the state's, amber under an hour, muted once passed. */
|
|
204
|
-
export const EXPIRING_SOON_MS = 60 * 60 * 1000;
|
|
205
|
-
export const grantTimeIntent = (expiresAt: string | undefined, now: number): TReqoreIntent => {
|
|
206
|
-
const left = millisUntil(expiresAt, now);
|
|
207
|
-
if (Number.isNaN(left)) return 'success';
|
|
208
|
-
if (left <= 0) return 'muted';
|
|
209
|
-
return left < EXPIRING_SOON_MS ? 'warning' : 'success';
|
|
210
|
-
};
|