@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.
Files changed (70) hide show
  1. package/.claude/CLAUDE.md +0 -1
  2. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts +1 -13
  3. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts.map +1 -1
  4. package/dist/components/supportTicket/InterfaceReferenceTags.js +4 -11
  5. package/dist/components/supportTicket/InterfaceReferenceTags.js.map +1 -1
  6. package/dist/components/supportTicket/ReferencePicker.d.ts.map +1 -1
  7. package/dist/components/supportTicket/ReferencePicker.js +1 -1
  8. package/dist/components/supportTicket/ReferencePicker.js.map +1 -1
  9. package/dist/components/supportTicket/index.d.ts +0 -2
  10. package/dist/components/supportTicket/index.d.ts.map +1 -1
  11. package/dist/components/supportTicket/index.js +0 -2
  12. package/dist/components/supportTicket/index.js.map +1 -1
  13. package/dist/components/supportTicket/meta.d.ts +2 -62
  14. package/dist/components/supportTicket/meta.d.ts.map +1 -1
  15. package/dist/components/supportTicket/meta.js +3 -116
  16. package/dist/components/supportTicket/meta.js.map +1 -1
  17. package/dist/components/supportTicket/ticketModel.d.ts +0 -10
  18. package/dist/components/supportTicket/ticketModel.d.ts.map +1 -1
  19. package/dist/components/ticketReferences/TicketReferences.d.ts +1 -10
  20. package/dist/components/ticketReferences/TicketReferences.d.ts.map +1 -1
  21. package/dist/components/ticketReferences/TicketReferences.js +8 -12
  22. package/dist/components/ticketReferences/TicketReferences.js.map +1 -1
  23. package/dist/components/ticketThread/TicketThread.d.ts +1 -30
  24. package/dist/components/ticketThread/TicketThread.d.ts.map +1 -1
  25. package/dist/components/ticketThread/TicketThread.js +13 -51
  26. package/dist/components/ticketThread/TicketThread.js.map +1 -1
  27. package/dist/components/ticketThread/index.d.ts +1 -1
  28. package/dist/components/ticketThread/index.d.ts.map +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers/StorageProvider.d.ts +0 -11
  33. package/dist/providers/StorageProvider.d.ts.map +1 -1
  34. package/dist/providers/StorageProvider.js +3 -21
  35. package/dist/providers/StorageProvider.js.map +1 -1
  36. package/dist/stores/currentUser/currentUser.d.ts +0 -42
  37. package/dist/stores/currentUser/currentUser.d.ts.map +1 -1
  38. package/dist/stores/currentUser/currentUser.js.map +1 -1
  39. package/package.json +9 -9
  40. package/src/components/form/engine/FormEngine.stories.tsx +5 -8
  41. package/src/components/form/fields/array/ArrayAutoField.stories.tsx +3 -6
  42. package/src/components/form/fields/boolean/Boolean.stories.tsx +3 -7
  43. package/src/components/form/fields/markdown/Markdown.stories.tsx +0 -6
  44. package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +1 -4
  45. package/src/components/form/fields/template/TemplateField.stories.tsx +0 -4
  46. package/src/components/supportTicket/InterfaceReferenceTags.stories.tsx +0 -56
  47. package/src/components/supportTicket/InterfaceReferenceTags.tsx +7 -27
  48. package/src/components/supportTicket/ReferencePicker.tsx +1 -4
  49. package/src/components/supportTicket/index.ts +0 -2
  50. package/src/components/supportTicket/meta.ts +4 -156
  51. package/src/components/supportTicket/ticketModel.ts +0 -10
  52. package/src/components/ticketReferences/TicketReferences.stories.tsx +0 -40
  53. package/src/components/ticketReferences/TicketReferences.tsx +10 -24
  54. package/src/components/ticketThread/TicketThread.stories.tsx +1 -103
  55. package/src/components/ticketThread/TicketThread.tsx +15 -131
  56. package/src/components/ticketThread/index.ts +0 -1
  57. package/src/index.tsx +0 -1
  58. package/src/providers/StorageProvider.tsx +3 -20
  59. package/src/stores/currentUser/currentUser.tsx +0 -43
  60. package/dist/components/supportTicket/WorkspaceAccessStatus.d.ts +0 -55
  61. package/dist/components/supportTicket/WorkspaceAccessStatus.d.ts.map +0 -1
  62. package/dist/components/supportTicket/WorkspaceAccessStatus.js +0 -79
  63. package/dist/components/supportTicket/WorkspaceAccessStatus.js.map +0 -1
  64. package/dist/components/supportTicket/accessMeta.d.ts +0 -50
  65. package/dist/components/supportTicket/accessMeta.d.ts.map +0 -1
  66. package/dist/components/supportTicket/accessMeta.js +0 -174
  67. package/dist/components/supportTicket/accessMeta.js.map +0 -1
  68. package/src/components/supportTicket/WorkspaceAccessStatus.stories.tsx +0 -105
  69. package/src/components/supportTicket/WorkspaceAccessStatus.tsx +0 -176
  70. package/src/components/supportTicket/accessMeta.ts +0 -210
@@ -1,79 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkspaceAccessStatus = exports.describeWorkspaceAccess = void 0;
4
- var jsx_runtime_1 = require("react/jsx-runtime");
5
- var reqore_1 = require("@qoretechnologies/reqore");
6
- var accessMeta_1 = require("./accessMeta");
7
- var TicketHeader_1 = require("./TicketHeader");
8
- var grantedBy = function (grant, viewerRole) {
9
- if (grant.created_by_type === 'system')
10
- return 'automatically';
11
- if (grant.created_by_type === 'customer' || !grant.created_by_type) {
12
- return viewerRole === 'customer' ? 'by you' : 'by the customer';
13
- }
14
- return 'by support';
15
- };
16
- /** The sentence, its mark and its colour for the state the props describe. */
17
- var describeWorkspaceAccess = function (_a) {
18
- var _b, _c;
19
- var grant = _a.grant, request = _a.request, policy = _a.policy, viewerRole = _a.viewerRole, now = _a.now;
20
- if (grant && grant.state === 'active') {
21
- var left = (0, accessMeta_1.millisUntil)(grant.expires_at, now);
22
- if (!Number.isNaN(left) && left <= 0) {
23
- return {
24
- text: "Access ended ".concat((0, accessMeta_1.formatRelativeTime)(grant.expires_at, now)),
25
- tooltip: (0, accessMeta_1.formatInstant)(grant.expires_at),
26
- intent: 'muted',
27
- icon: 'HourglassLine',
28
- };
29
- }
30
- var ends = grant.expires_at ? " \u00B7 ends ".concat((0, accessMeta_1.formatRelativeTime)(grant.expires_at, now)) : '';
31
- return {
32
- text: "Granted ".concat(grantedBy(grant, viewerRole)).concat(ends),
33
- tooltip: grant.expires_at
34
- ? "Until ".concat((0, accessMeta_1.formatInstant)(grant.expires_at)).concat(grant.until_resolved ? ', or when the ticket is resolved' : '')
35
- : undefined,
36
- intent: (0, accessMeta_1.grantTimeIntent)(grant.expires_at, now),
37
- icon: 'ShieldCheckLine',
38
- };
39
- }
40
- if (grant) {
41
- var meta = (0, accessMeta_1.supportGrantStateMeta)(grant.state);
42
- var cause = (0, accessMeta_1.supportGrantEndCauseLabel)(grant.end_cause);
43
- var when = (0, accessMeta_1.formatRelativeTime)((_b = grant.ended_at) !== null && _b !== void 0 ? _b : grant.expires_at, now);
44
- return {
45
- text: "Access ".concat(meta.label.toLowerCase()).concat(cause && cause !== meta.label.toLowerCase() ? ": ".concat(cause) : '').concat(when ? " \u00B7 ".concat(when) : ''),
46
- tooltip: (0, accessMeta_1.formatInstant)((_c = grant.ended_at) !== null && _c !== void 0 ? _c : grant.expires_at) || undefined,
47
- intent: meta.intent,
48
- icon: meta.icon,
49
- };
50
- }
51
- if (request) {
52
- var since = (0, accessMeta_1.formatRelativeTime)(request.requested_at, now);
53
- var duration = request.suggested_duration ? " for ".concat((0, accessMeta_1.supportAccessDurationLabel)(request.suggested_duration)) : '';
54
- return {
55
- text: viewerRole === 'customer'
56
- ? "Qorus Support asks for access".concat(duration, " \u00B7 ").concat(since)
57
- : "Requested".concat(duration, " \u00B7 awaiting the customer \u00B7 ").concat(since),
58
- tooltip: (0, accessMeta_1.formatInstant)(request.requested_at),
59
- intent: 'pending',
60
- icon: 'TimeLine',
61
- };
62
- }
63
- if (policy === 'never') {
64
- return {
65
- text: viewerRole === 'customer' ? 'Off: your setting is never' : "Not allowed: the account's setting is never",
66
- intent: 'danger',
67
- icon: 'ShieldCrossLine',
68
- };
69
- }
70
- return { text: 'None', intent: 'muted', icon: 'ShieldLine', muted: true };
71
- };
72
- exports.describeWorkspaceAccess = describeWorkspaceAccess;
73
- var WorkspaceAccessStatus = function (_a) {
74
- var grant = _a.grant, request = _a.request, policy = _a.policy, viewerRole = _a.viewerRole, now = _a.now, action = _a.action, _b = _a.size, size = _b === void 0 ? 'small' : _b, className = _a.className;
75
- var _c = (0, exports.describeWorkspaceAccess)({ grant: grant, request: request, policy: policy, viewerRole: viewerRole, now: now }), text = _c.text, tooltip = _c.tooltip, intent = _c.intent, icon = _c.icon, muted = _c.muted;
76
- return ((0, jsx_runtime_1.jsxs)(TicketHeader_1.TicketPersonValue, { className: "reqore-workspace-access-status".concat(className ? " ".concat(className) : ''), children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreIcon, { icon: icon, size: 'tiny', color: intent }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreSpan, { size: size, tooltip: tooltip, effect: muted ? { opacity: 0.5 } : undefined, children: text }), action ? ((0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { size: size, minimal: true, flat: true, icon: action.icon, intent: action.intent, loading: action.loading, tooltip: action.tooltip, onClick: action.onClick, className: 'reqore-workspace-access-status-action', children: action.label })) : null] }));
77
- };
78
- exports.WorkspaceAccessStatus = WorkspaceAccessStatus;
79
- //# sourceMappingURL=WorkspaceAccessStatus.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WorkspaceAccessStatus.js","sourceRoot":"","sources":["../../../src/components/supportTicket/WorkspaceAccessStatus.tsx"],"names":[],"mappings":"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"}
@@ -1,50 +0,0 @@
1
- import { TReqoreIntent } from '@qoretechnologies/reqore/dist/constants/theme';
2
- import { ITicketEnumMeta } from './meta';
3
- /** The account's support access setting, least to most restrictive. */
4
- export type TSupportAccessPolicy = 'auto' | 'ask' | 'never';
5
- /** Where the governing setting came from. `default` when the customer never chose;
6
- * `owner` when the workspace's billing owner's stricter setting governs the ticket. */
7
- export type TSupportAccessPolicySource = 'default' | 'signup' | 'prompt' | 'settings' | 'admin' | 'owner';
8
- export type TSupportGrantState = 'active' | 'revoked' | 'expired';
9
- export type TSupportGrantEndCause = 'customer_revoked' | 'staff_revoked' | 'superseded' | 'ticket_resolved' | 'ticket_closed' | 'policy_changed' | 'account_erased' | 'workspace_deleted' | 'expired';
10
- /** A duration a staff request suggests; the customer's Grant answers exactly it. */
11
- export type TSupportAccessDuration = '24h' | '72h' | '7d' | 'until_resolved';
12
- /** The grant's own audit trail (`…/access` `audit`, the account's access log). */
13
- export type TSupportAccessAuditAction = 'policy_set' | 'access_requested' | 'granted' | 'extended' | 'revoked' | 'expired' | 'used' | 'use_refused' | 'session_started' | 'session_ended';
14
- /** A mark with a sentence: the setting's meaning is what a customer decides on. */
15
- export interface ISupportAccessMeta extends ITicketEnumMeta {
16
- description?: string;
17
- }
18
- export declare const SUPPORT_ACCESS_POLICY_META: Record<TSupportAccessPolicy, ISupportAccessMeta>;
19
- /** The setting's mark; an unknown value still reads as words. */
20
- export declare const supportAccessPolicyMeta: (value: string | undefined) => ISupportAccessMeta;
21
- export declare const SUPPORT_ACCESS_POLICY_SOURCE_LABEL: Record<TSupportAccessPolicySource, string>;
22
- export declare const supportAccessPolicySourceLabel: (source: string | undefined) => string;
23
- export declare const SUPPORT_GRANT_STATE_META: Record<TSupportGrantState, ISupportAccessMeta>;
24
- export declare const supportGrantStateMeta: (value: string | undefined) => ISupportAccessMeta;
25
- export declare const SUPPORT_GRANT_END_CAUSE_LABEL: Record<TSupportGrantEndCause, string>;
26
- export declare const supportGrantEndCauseLabel: (cause: string | undefined) => string | undefined;
27
- export declare const SUPPORT_ACCESS_DURATION_LABEL: Record<TSupportAccessDuration, string>;
28
- export declare const supportAccessDurationLabel: (duration: string | undefined) => string;
29
- /** The grant's own trail, as a customer's access log or a staff access view lists it. */
30
- export declare const SUPPORT_ACCESS_AUDIT_ACTION_META: Record<TSupportAccessAuditAction, ISupportAccessMeta>;
31
- /** An action the plane writes that this vocabulary has not caught up with still renders. */
32
- export declare const supportAccessAuditActionMeta: (action: string) => ISupportAccessMeta;
33
- /**
34
- * "in 3 hours" / "2 days ago" against a clock the caller passes, so a story freezes it
35
- * and two surfaces reading the same grant agree. An unparsable instant is an empty
36
- * string, never "NaN years ago".
37
- *
38
- * Not `epoch-timeago` (what `ReqoreTimeAgo` and `TicketReferences` use): it speaks only
39
- * of the past and reads the real clock, so it can neither say "in 3 hours" for a grant
40
- * that is still running nor hold still in a story.
41
- */
42
- export declare const formatRelativeTime: (iso: string | undefined, now: number, locale?: string) => string;
43
- /** The absolute instant, for a tooltip beside a relative one. */
44
- export declare const formatInstant: (iso: string | undefined, locale?: string) => string;
45
- /** Milliseconds until an instant; negative once it passed; NaN for nothing. */
46
- export declare const millisUntil: (iso: string | undefined, now: number) => number;
47
- /** The intent a grant's remaining time reads as: the state's, amber under an hour, muted once passed. */
48
- export declare const EXPIRING_SOON_MS: number;
49
- export declare const grantTimeIntent: (expiresAt: string | undefined, now: number) => TReqoreIntent;
50
- //# sourceMappingURL=accessMeta.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accessMeta.d.ts","sourceRoot":"","sources":["../../../src/components/supportTicket/accessMeta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+CAA+C,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAqB,MAAM,QAAQ,CAAC;AAa5D,uEAAuE;AACvE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5D;wFACwF;AACxF,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1G,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAElE,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,eAAe,GACf,YAAY,GACZ,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,CAAC;AAEd,oFAAoF;AACpF,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,gBAAgB,CAAC;AAE7E,kFAAkF;AAClF,MAAM,MAAM,yBAAyB,GACjC,YAAY,GACZ,kBAAkB,GAClB,SAAS,GACT,UAAU,GACV,SAAS,GACT,SAAS,GACT,MAAM,GACN,aAAa,GACb,iBAAiB,GACjB,eAAe,CAAC;AAEpB,mFAAmF;AACnF,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAmBvF,CAAC;AACF,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,UA1B1B,MAAM,GAAG,SAAS,KAAG,kBA0B0C,CAAC;AAE1E,eAAO,MAAM,kCAAkC,EAAE,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAOzF,CAAC;AACF,eAAO,MAAM,8BAA8B,WAAY,MAAM,GAAG,SAAS,KAAG,MAE3C,CAAC;AAElC,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAInF,CAAC;AACF,eAAO,MAAM,qBAAqB,UA7CxB,MAAM,GAAG,SAAS,KAAG,kBA6CsC,CAAC;AAEtE,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAU/E,CAAC;AACF,eAAO,MAAM,yBAAyB,UAAW,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SACqC,CAAC;AAErH,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAKhF,CAAC;AACF,eAAO,MAAM,0BAA0B,aAAc,MAAM,GAAG,SAAS,KAAG,MAEvC,CAAC;AAEpC,yFAAyF;AACzF,eAAO,MAAM,gCAAgC,EAAE,MAAM,CAAC,yBAAyB,EAAE,kBAAkB,CAWlG,CAAC;AACF,4FAA4F;AAC5F,eAAO,MAAM,4BAA4B,WAAY,MAAM,KAAG,kBAK3D,CAAC;AAcJ;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,QAAS,MAAM,GAAG,SAAS,OAAO,MAAM,sBAAkB,MAYxF,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,aAAa,QAAS,MAAM,GAAG,SAAS,sBAAqB,MAMzE,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,WAAW,QAAS,MAAM,GAAG,SAAS,OAAO,MAAM,KAAG,MACjB,CAAC;AAEnD,yGAAyG;AACzG,eAAO,MAAM,gBAAgB,QAAiB,CAAC;AAC/C,eAAO,MAAM,eAAe,cAAe,MAAM,GAAG,SAAS,OAAO,MAAM,KAAG,aAK5E,CAAC"}
@@ -1,174 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.grantTimeIntent = exports.EXPIRING_SOON_MS = exports.millisUntil = exports.formatInstant = exports.formatRelativeTime = exports.supportAccessAuditActionMeta = exports.SUPPORT_ACCESS_AUDIT_ACTION_META = exports.supportAccessDurationLabel = exports.SUPPORT_ACCESS_DURATION_LABEL = exports.supportGrantEndCauseLabel = exports.SUPPORT_GRANT_END_CAUSE_LABEL = exports.supportGrantStateMeta = exports.SUPPORT_GRANT_STATE_META = exports.supportAccessPolicySourceLabel = exports.SUPPORT_ACCESS_POLICY_SOURCE_LABEL = exports.supportAccessPolicyMeta = exports.SUPPORT_ACCESS_POLICY_META = void 0;
15
- var meta_1 = require("./meta");
16
- /** `idle_paused` → "Idle paused": a wire value as words. */
17
- var UNKNOWN = { label: 'Unknown', intent: 'muted', icon: 'QuestionLine' };
18
- var lookup = function (table) {
19
- return function (value) {
20
- var _a;
21
- return value === undefined
22
- ? UNKNOWN
23
- : ((_a = table[value]) !== null && _a !== void 0 ? _a : __assign(__assign({}, UNKNOWN), { label: (0, meta_1.humaniseWireValue)(value) }));
24
- };
25
- };
26
- exports.SUPPORT_ACCESS_POLICY_META = {
27
- auto: {
28
- label: 'Granted automatically',
29
- intent: 'success',
30
- icon: 'ShieldCheckLine',
31
- description: 'Read-only access for Qorus Support is granted automatically on every ticket filed.',
32
- },
33
- ask: {
34
- label: 'Ask the customer',
35
- intent: 'info',
36
- icon: 'QuestionAnswerLine',
37
- description: 'Support asks on each ticket; the customer decides whether to grant access.',
38
- },
39
- never: {
40
- label: 'Never',
41
- intent: 'danger',
42
- icon: 'ShieldCrossLine',
43
- description: 'No workspace access for Qorus Support. Support asks for information in the thread instead.',
44
- },
45
- };
46
- /** The setting's mark; an unknown value still reads as words. */
47
- exports.supportAccessPolicyMeta = lookup(exports.SUPPORT_ACCESS_POLICY_META);
48
- exports.SUPPORT_ACCESS_POLICY_SOURCE_LABEL = {
49
- default: 'the default, never chosen',
50
- signup: 'chosen at sign-up',
51
- prompt: 'chosen when first asked',
52
- settings: 'chosen in the account settings',
53
- admin: 'set by Qorus staff',
54
- owner: "the workspace owner's stricter setting",
55
- };
56
- var supportAccessPolicySourceLabel = function (source) {
57
- return (source && exports.SUPPORT_ACCESS_POLICY_SOURCE_LABEL[source]) ||
58
- (0, meta_1.humaniseWireValue)(source !== null && source !== void 0 ? source : '');
59
- };
60
- exports.supportAccessPolicySourceLabel = supportAccessPolicySourceLabel;
61
- exports.SUPPORT_GRANT_STATE_META = {
62
- active: { label: 'Active', intent: 'success', icon: 'ShieldCheckLine' },
63
- revoked: { label: 'Revoked', intent: 'danger', icon: 'ShieldCrossLine' },
64
- expired: { label: 'Expired', intent: 'muted', icon: 'HourglassLine' },
65
- };
66
- exports.supportGrantStateMeta = lookup(exports.SUPPORT_GRANT_STATE_META);
67
- exports.SUPPORT_GRANT_END_CAUSE_LABEL = {
68
- customer_revoked: 'ended by the customer',
69
- staff_revoked: 'ended by support',
70
- superseded: 'extended into a new grant',
71
- ticket_resolved: 'the ticket was resolved',
72
- ticket_closed: 'the ticket was closed',
73
- policy_changed: "the account's setting changed",
74
- account_erased: 'the account was erased',
75
- workspace_deleted: 'the workspace was deleted',
76
- expired: 'expired',
77
- };
78
- var supportGrantEndCauseLabel = function (cause) { var _a; return cause ? ((_a = exports.SUPPORT_GRANT_END_CAUSE_LABEL[cause]) !== null && _a !== void 0 ? _a : (0, meta_1.humaniseWireValue)(cause)) : undefined; };
79
- exports.supportGrantEndCauseLabel = supportGrantEndCauseLabel;
80
- exports.SUPPORT_ACCESS_DURATION_LABEL = {
81
- '24h': '24 hours',
82
- '72h': '3 days',
83
- '7d': '7 days',
84
- until_resolved: 'until the ticket is resolved',
85
- };
86
- var supportAccessDurationLabel = function (duration) {
87
- return (duration && exports.SUPPORT_ACCESS_DURATION_LABEL[duration]) ||
88
- (0, meta_1.humaniseWireValue)(duration !== null && duration !== void 0 ? duration : '');
89
- };
90
- exports.supportAccessDurationLabel = supportAccessDurationLabel;
91
- /** The grant's own trail, as a customer's access log or a staff access view lists it. */
92
- exports.SUPPORT_ACCESS_AUDIT_ACTION_META = {
93
- policy_set: { label: 'Setting changed', intent: 'info', icon: 'Settings3Line' },
94
- access_requested: { label: 'Access requested', intent: 'pending', icon: 'ShieldUserLine' },
95
- granted: { label: 'Access granted', intent: 'success', icon: 'ShieldCheckLine' },
96
- extended: { label: 'Access extended', intent: 'info', icon: 'TimerLine' },
97
- revoked: { label: 'Access revoked', intent: 'danger', icon: 'ShieldCrossLine' },
98
- expired: { label: 'Access expired', intent: 'muted', icon: 'HourglassLine' },
99
- used: { label: 'Workspace read', intent: 'info', icon: 'EyeLine' },
100
- use_refused: { label: 'Read refused', intent: 'warning', icon: 'ForbidLine' },
101
- session_started: { label: 'IDE session started', intent: 'info', icon: 'ExternalLinkLine' },
102
- session_ended: { label: 'IDE session ended', intent: 'muted', icon: 'LogoutBoxLine' },
103
- };
104
- /** An action the plane writes that this vocabulary has not caught up with still renders. */
105
- var supportAccessAuditActionMeta = function (action) {
106
- var _a;
107
- return (_a = exports.SUPPORT_ACCESS_AUDIT_ACTION_META[action]) !== null && _a !== void 0 ? _a : __assign(__assign({}, UNKNOWN), { icon: 'HistoryLine', label: (0, meta_1.humaniseWireValue)(action) });
108
- };
109
- exports.supportAccessAuditActionMeta = supportAccessAuditActionMeta;
110
- /* ── time, against a clock the caller owns ───────────────────────────────────── */
111
- var RELATIVE_UNITS = [
112
- ['year', 60 * 60 * 24 * 365],
113
- ['month', 60 * 60 * 24 * 30],
114
- ['week', 60 * 60 * 24 * 7],
115
- ['day', 60 * 60 * 24],
116
- ['hour', 60 * 60],
117
- ['minute', 60],
118
- ['second', 1],
119
- ];
120
- /**
121
- * "in 3 hours" / "2 days ago" against a clock the caller passes, so a story freezes it
122
- * and two surfaces reading the same grant agree. An unparsable instant is an empty
123
- * string, never "NaN years ago".
124
- *
125
- * Not `epoch-timeago` (what `ReqoreTimeAgo` and `TicketReferences` use): it speaks only
126
- * of the past and reads the real clock, so it can neither say "in 3 hours" for a grant
127
- * that is still running nor hold still in a story.
128
- */
129
- var formatRelativeTime = function (iso, now, locale) {
130
- if (locale === void 0) { locale = 'en'; }
131
- if (!iso)
132
- return '';
133
- var then = new Date(iso).getTime();
134
- if (Number.isNaN(then))
135
- return '';
136
- var seconds = Math.round((then - now) / 1000);
137
- var rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
138
- for (var _i = 0, RELATIVE_UNITS_1 = RELATIVE_UNITS; _i < RELATIVE_UNITS_1.length; _i++) {
139
- var _a = RELATIVE_UNITS_1[_i], unit = _a[0], secondsInUnit = _a[1];
140
- if (Math.abs(seconds) >= secondsInUnit || unit === 'second') {
141
- return rtf.format(Math.round(seconds / secondsInUnit), unit);
142
- }
143
- }
144
- return '';
145
- };
146
- exports.formatRelativeTime = formatRelativeTime;
147
- /** The absolute instant, for a tooltip beside a relative one. */
148
- var formatInstant = function (iso, locale) {
149
- if (locale === void 0) { locale = 'en-GB'; }
150
- if (!iso)
151
- return '';
152
- var date = new Date(iso);
153
- return Number.isNaN(date.getTime())
154
- ? iso
155
- : date.toLocaleString(locale, { dateStyle: 'medium', timeStyle: 'short' });
156
- };
157
- exports.formatInstant = formatInstant;
158
- /** Milliseconds until an instant; negative once it passed; NaN for nothing. */
159
- var millisUntil = function (iso, now) {
160
- return iso ? new Date(iso).getTime() - now : Number.NaN;
161
- };
162
- exports.millisUntil = millisUntil;
163
- /** The intent a grant's remaining time reads as: the state's, amber under an hour, muted once passed. */
164
- exports.EXPIRING_SOON_MS = 60 * 60 * 1000;
165
- var grantTimeIntent = function (expiresAt, now) {
166
- var left = (0, exports.millisUntil)(expiresAt, now);
167
- if (Number.isNaN(left))
168
- return 'success';
169
- if (left <= 0)
170
- return 'muted';
171
- return left < exports.EXPIRING_SOON_MS ? 'warning' : 'success';
172
- };
173
- exports.grantTimeIntent = grantTimeIntent;
174
- //# sourceMappingURL=accessMeta.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accessMeta.js","sourceRoot":"","sources":["../../../src/components/supportTicket/accessMeta.ts"],"names":[],"mappings":"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"}
@@ -1,105 +0,0 @@
1
- import { StoryObj } from '@storybook/react-vite';
2
- import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
3
- import { StoryMeta } from '../../types';
4
- import { TicketHeader } from './TicketHeader';
5
- import { IWorkspaceAccessStatusProps, WorkspaceAccessStatus } from './WorkspaceAccessStatus';
6
-
7
- /** The frozen clock every relative time here is spoken against. */
8
- const NOW = Date.parse('2026-10-19T12:00:00Z');
9
- const at = (minutes: number) => new Date(NOW + minutes * 60_000).toISOString();
10
-
11
- const ACTIVE = { state: 'active', created_by_type: 'customer', issued_at: at(-180), expires_at: at(2 * 24 * 60), until_resolved: false };
12
-
13
- /*
14
- * One read-only value with many states: the review grid is one story, every state a
15
- * labelled rail row, staff beside customer — one capture to look at, and a wrong word
16
- * in any row still fails the play by name. The clicking case and the phone case are
17
- * their own stories.
18
- */
19
- const STATES: { label: string; props: Omit<IWorkspaceAccessStatusProps, 'now'> }[] = [
20
- { label: 'Active · staff', props: { viewerRole: 'staff', grant: ACTIVE } },
21
- { label: 'Active · customer', props: { viewerRole: 'customer', grant: ACTIVE } },
22
- { label: 'Expiring soon', props: { viewerRole: 'staff', grant: { ...ACTIVE, expires_at: at(40) } } },
23
- { label: 'Ended on the clock', props: { viewerRole: 'staff', grant: { ...ACTIVE, expires_at: at(-5) } } },
24
- // six days, not seven: at seven the clock says "next week", which reads worse
25
- { label: 'Automatic, until resolved', props: { viewerRole: 'staff', grant: { ...ACTIVE, created_by_type: 'system', until_resolved: true, expires_at: at(6 * 24 * 60) } } },
26
- { label: 'Revoked', props: { viewerRole: 'staff', grant: { state: 'revoked', created_by_type: 'customer', issued_at: at(-3 * 24 * 60), expires_at: at(-24 * 60), ended_at: at(-26 * 60), end_cause: 'staff_revoked' } } },
27
- { label: 'Pending · staff', props: { viewerRole: 'staff', request: { requested_at: at(-45), suggested_duration: '72h' } } },
28
- { label: 'Pending · customer', props: { viewerRole: 'customer', request: { requested_at: at(-45), suggested_duration: '24h' } } },
29
- { label: 'Setting is never', props: { viewerRole: 'staff', policy: 'never' } },
30
- // the row label must not repeat the value's own word, or the play finds two
31
- { label: 'Nothing yet', props: { viewerRole: 'staff' } },
32
- ];
33
-
34
- const meta = {
35
- component: WorkspaceAccessStatus,
36
- title: 'Components/WorkspaceAccessStatus',
37
- args: { viewerRole: 'staff', now: NOW, grant: ACTIVE },
38
- // the value sits in the ticket rail, so each story renders it in one
39
- render: (args) => <TicketHeader padding={14} properties={[{ label: 'Workspace access', value: <WorkspaceAccessStatus {...args} /> }]} />,
40
- } as StoryMeta<typeof WorkspaceAccessStatus>;
41
-
42
- export default meta;
43
- type Story = StoryObj<typeof meta>;
44
-
45
- export const States: Story = {
46
- parameters: {
47
- docs: {
48
- description: {
49
- story:
50
- 'Renders every state of the value as a labelled rail row against one frozen clock: an active grant from the staff and the customer side, one expiring within the hour (amber), one whose expiry passed (muted), an automatic grant until the ticket is resolved, a revoked one, an open request from both sides, a setting of "never", and none.',
51
- },
52
- },
53
- },
54
- render: () => (
55
- <TicketHeader
56
- padding={14}
57
- properties={STATES.map(({ label, props }) => ({ label, value: <WorkspaceAccessStatus {...props} now={NOW} /> }))}
58
- />
59
- ),
60
- async play({ canvasElement }) {
61
- const canvas = within(canvasElement);
62
- for (const text of [
63
- 'Granted by the customer · ends in 2 days',
64
- 'Granted by you · ends in 2 days',
65
- 'Granted by the customer · ends in 40 minutes',
66
- 'Access ended 5 minutes ago',
67
- 'Granted automatically · ends in 6 days',
68
- 'Access revoked: ended by support · yesterday',
69
- 'Requested for 3 days · awaiting the customer · 45 minutes ago',
70
- 'Qorus Support asks for access for 24 hours · 45 minutes ago',
71
- "Not allowed: the account's setting is never",
72
- 'None',
73
- ]) {
74
- await expect(canvas.getByText(text)).toBeInTheDocument();
75
- }
76
- },
77
- };
78
-
79
- export const Active: Story = {
80
- args: { action: { label: 'End access', icon: 'ShieldCrossLine', intent: 'danger', onClick: fn() } },
81
- parameters: {
82
- docs: {
83
- description: {
84
- story: 'Renders the staff value of an active grant with "End access" beside it — the one state that carries an action. Clicking the action calls it.',
85
- },
86
- },
87
- },
88
- async play({ canvasElement, args }) {
89
- const canvas = within(canvasElement);
90
- await expect(canvas.getByText('Granted by the customer · ends in 2 days')).toBeInTheDocument();
91
- await userEvent.click(canvas.getByText('End access'));
92
- await waitFor(() => expect(args.action?.onClick).toHaveBeenCalledTimes(1));
93
- },
94
- };
95
-
96
- export const Mobile: Story = {
97
- args: Active.args,
98
- parameters: {
99
- qlip: { viewport: { width: 390, height: 844 } },
100
- docs: { description: { story: 'Renders the active value with its action at 390px: the sentence truncates with an ellipsis before the action does, and the action keeps its label.' } },
101
- },
102
- async play({ canvasElement }) {
103
- await expect(within(canvasElement).getByText('End access')).toBeInTheDocument();
104
- },
105
- };
@@ -1,176 +0,0 @@
1
- import { ReqoreButton, ReqoreIcon, ReqoreSpan } from '@qoretechnologies/reqore';
2
- import { TSizes } from '@qoretechnologies/reqore/dist/constants/sizes';
3
- import { TReqoreIntent } from '@qoretechnologies/reqore/dist/constants/theme';
4
- import { IReqoreIconName } from '@qoretechnologies/reqore/dist/types/icons';
5
- import {
6
- formatInstant,
7
- formatRelativeTime,
8
- grantTimeIntent,
9
- millisUntil,
10
- supportAccessDurationLabel,
11
- supportGrantEndCauseLabel,
12
- supportGrantStateMeta,
13
- TSupportAccessPolicy,
14
- TSupportGrantState,
15
- } from './accessMeta';
16
- import { TTicketViewerRole } from './meta';
17
- import { TicketPersonValue } from './TicketHeader';
18
-
19
- /*
20
- * Where a ticket's workspace access stands, as one rail value: granted and for how
21
- * long, requested and waiting, refused by the setting, or none — with the one thing
22
- * the viewer may do about it beside it (the customer's Revoke, support's End access).
23
- * The customer's IDE and the staff portal show the same grant from opposite sides,
24
- * so the sentence is built here once and `viewerRole` picks the pronoun.
25
- *
26
- * The clock is the caller's (`now`): the component never reads the wall clock, so a
27
- * story freezes it and every surface on a page agrees on "ends in 2 days".
28
- */
29
-
30
- /** What the value needs of a grant: the plane's `SupportAccessGrant`, a subset. */
31
- export interface IWorkspaceAccessGrantSummary {
32
- state: TSupportGrantState | string;
33
- issued_at?: string;
34
- expires_at?: string;
35
- until_resolved?: boolean;
36
- created_by_type?: 'customer' | 'staff' | 'system' | string;
37
- ended_at?: string;
38
- end_cause?: string;
39
- }
40
-
41
- /** What the value needs of an open staff request. */
42
- export interface IWorkspaceAccessRequestSummary {
43
- requested_at: string;
44
- suggested_duration?: string;
45
- }
46
-
47
- export interface IWorkspaceAccessStatusAction {
48
- label: string;
49
- icon?: IReqoreIconName;
50
- intent?: TReqoreIntent;
51
- onClick: () => void;
52
- loading?: boolean;
53
- tooltip?: string;
54
- }
55
-
56
- export interface IWorkspaceAccessStatusProps {
57
- /** the ticket's active grant, or the last one when none is active */
58
- grant?: IWorkspaceAccessGrantSummary;
59
- /** the open staff request, when there is one and no active grant */
60
- request?: IWorkspaceAccessRequestSummary;
61
- /** the account's setting; `never` is said when nothing else is there to say */
62
- policy?: TSupportAccessPolicy | string;
63
- /** who is reading: decides "by you" against "by the customer" */
64
- viewerRole: TTicketViewerRole;
65
- /** the clock, in ms; a story passes a fixed one */
66
- now: number;
67
- /** the one thing the viewer may do right now, rendered beside the sentence */
68
- action?: IWorkspaceAccessStatusAction;
69
- /** the rail's size by default */
70
- size?: TSizes;
71
- className?: string;
72
- }
73
-
74
- const grantedBy = (grant: IWorkspaceAccessGrantSummary, viewerRole: TTicketViewerRole): string => {
75
- if (grant.created_by_type === 'system') return 'automatically';
76
- if (grant.created_by_type === 'customer' || !grant.created_by_type) {
77
- return viewerRole === 'customer' ? 'by you' : 'by the customer';
78
- }
79
- return 'by support';
80
- };
81
-
82
- /** The sentence, its mark and its colour for the state the props describe. */
83
- export const describeWorkspaceAccess = (
84
- { grant, request, policy, viewerRole, now }: Pick<IWorkspaceAccessStatusProps, 'grant' | 'request' | 'policy' | 'viewerRole' | 'now'>
85
- ): { text: string; tooltip?: string; intent: TReqoreIntent; icon: IReqoreIconName; muted?: boolean } => {
86
- if (grant && grant.state === 'active') {
87
- const left = millisUntil(grant.expires_at, now);
88
- if (!Number.isNaN(left) && left <= 0) {
89
- return {
90
- text: `Access ended ${formatRelativeTime(grant.expires_at, now)}`,
91
- tooltip: formatInstant(grant.expires_at),
92
- intent: 'muted',
93
- icon: 'HourglassLine',
94
- };
95
- }
96
- const ends = grant.expires_at ? ` · ends ${formatRelativeTime(grant.expires_at, now)}` : '';
97
- return {
98
- text: `Granted ${grantedBy(grant, viewerRole)}${ends}`,
99
- tooltip: grant.expires_at
100
- ? `Until ${formatInstant(grant.expires_at)}${grant.until_resolved ? ', or when the ticket is resolved' : ''}`
101
- : undefined,
102
- intent: grantTimeIntent(grant.expires_at, now),
103
- icon: 'ShieldCheckLine',
104
- };
105
- }
106
- if (grant) {
107
- const meta = supportGrantStateMeta(grant.state);
108
- const cause = supportGrantEndCauseLabel(grant.end_cause);
109
- const when = formatRelativeTime(grant.ended_at ?? grant.expires_at, now);
110
- return {
111
- text: `Access ${meta.label.toLowerCase()}${cause && cause !== meta.label.toLowerCase() ? `: ${cause}` : ''}${when ? ` · ${when}` : ''}`,
112
- tooltip: formatInstant(grant.ended_at ?? grant.expires_at) || undefined,
113
- intent: meta.intent,
114
- icon: meta.icon,
115
- };
116
- }
117
- if (request) {
118
- const since = formatRelativeTime(request.requested_at, now);
119
- const duration = request.suggested_duration ? ` for ${supportAccessDurationLabel(request.suggested_duration)}` : '';
120
- return {
121
- text:
122
- viewerRole === 'customer'
123
- ? `Qorus Support asks for access${duration} · ${since}`
124
- : `Requested${duration} · awaiting the customer · ${since}`,
125
- tooltip: formatInstant(request.requested_at),
126
- intent: 'pending',
127
- icon: 'TimeLine',
128
- };
129
- }
130
- if (policy === 'never') {
131
- return {
132
- text: viewerRole === 'customer' ? 'Off: your setting is never' : "Not allowed: the account's setting is never",
133
- intent: 'danger',
134
- icon: 'ShieldCrossLine',
135
- };
136
- }
137
- return { text: 'None', intent: 'muted', icon: 'ShieldLine', muted: true };
138
- };
139
-
140
- export const WorkspaceAccessStatus = ({
141
- grant,
142
- request,
143
- policy,
144
- viewerRole,
145
- now,
146
- action,
147
- size = 'small',
148
- className,
149
- }: IWorkspaceAccessStatusProps) => {
150
- const { text, tooltip, intent, icon, muted } = describeWorkspaceAccess({ grant, request, policy, viewerRole, now });
151
- return (
152
- <TicketPersonValue className={`reqore-workspace-access-status${className ? ` ${className}` : ''}`}>
153
- {/* intent as a dot, the way the rail's other state values read: the colour
154
- carries the state without a saturated chip in a row of reference material */}
155
- <ReqoreIcon icon={icon} size='tiny' color={intent as never} />
156
- <ReqoreSpan size={size} tooltip={tooltip} effect={muted ? { opacity: 0.5 } : undefined}>
157
- {text}
158
- </ReqoreSpan>
159
- {action ? (
160
- <ReqoreButton
161
- size={size}
162
- minimal
163
- flat
164
- icon={action.icon}
165
- intent={action.intent}
166
- loading={action.loading}
167
- tooltip={action.tooltip}
168
- onClick={action.onClick}
169
- className='reqore-workspace-access-status-action'
170
- >
171
- {action.label}
172
- </ReqoreButton>
173
- ) : null}
174
- </TicketPersonValue>
175
- );
176
- };