@qoretechnologies/reqraft 0.10.65 → 0.10.66-pr.145.g32331ea
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/dist/components/form/engine/CompactRow.d.ts.map +1 -1
- package/dist/components/form/engine/CompactRow.js +128 -24
- package/dist/components/form/engine/CompactRow.js.map +1 -1
- package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
- package/dist/components/form/engine/CompactToolbar.js +78 -15
- package/dist/components/form/engine/CompactToolbar.js.map +1 -1
- package/dist/components/form/engine/FormEngine.d.ts +48 -1
- package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
- package/dist/components/form/engine/FormEngine.js +243 -85
- package/dist/components/form/engine/FormEngine.js.map +1 -1
- package/dist/components/form/engine/OptionFieldMessages.d.ts +18 -2
- package/dist/components/form/engine/OptionFieldMessages.d.ts.map +1 -1
- package/dist/components/form/engine/OptionFieldMessages.js +22 -3
- package/dist/components/form/engine/OptionFieldMessages.js.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.js +27 -1
- package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
- package/dist/components/form/engine/compactRowContext.d.ts +5 -0
- package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowContext.js.map +1 -1
- package/dist/components/form/engine/compactRowStyles.d.ts +12 -0
- package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
- package/dist/components/form/engine/compactRowStyles.js +72 -39
- package/dist/components/form/engine/compactRowStyles.js.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.d.ts +3 -0
- package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
- package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
- package/dist/components/form/engine/formAppearance.d.ts +48 -0
- package/dist/components/form/engine/formAppearance.d.ts.map +1 -0
- package/dist/components/form/engine/formAppearance.js +50 -0
- package/dist/components/form/engine/formAppearance.js.map +1 -0
- package/dist/components/form/engine/readFirst.d.ts +14 -2
- package/dist/components/form/engine/readFirst.d.ts.map +1 -1
- package/dist/components/form/engine/readFirst.js +6 -2
- package/dist/components/form/engine/readFirst.js.map +1 -1
- package/dist/components/form/engine/rowFocus.d.ts +9 -1
- package/dist/components/form/engine/rowFocus.d.ts.map +1 -1
- package/dist/components/form/engine/rowFocus.js +17 -5
- package/dist/components/form/engine/rowFocus.js.map +1 -1
- package/dist/components/form/fields/ChoiceGroupHeading.d.ts +21 -0
- package/dist/components/form/fields/ChoiceGroupHeading.d.ts.map +1 -0
- package/dist/components/form/fields/ChoiceGroupHeading.js +33 -0
- package/dist/components/form/fields/ChoiceGroupHeading.js.map +1 -0
- package/dist/components/form/fields/Field.d.ts.map +1 -1
- package/dist/components/form/fields/Field.js +5 -3
- package/dist/components/form/fields/Field.js.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
- package/dist/components/form/fields/allowed-values/AllowedValues.js +4 -2
- package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
- package/dist/components/form/fields/radio-group/RadioGroup.d.ts.map +1 -1
- package/dist/components/form/fields/radio-group/RadioGroup.js +13 -7
- package/dist/components/form/fields/radio-group/RadioGroup.js.map +1 -1
- package/dist/components/form/index.d.ts +1 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +1 -0
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/supportTicket/TicketHeader.d.ts.map +1 -1
- package/dist/components/supportTicket/TicketHeader.js +4 -1
- package/dist/components/supportTicket/TicketHeader.js.map +1 -1
- package/dist/components/supportTicket/TicketReplyBox.d.ts.map +1 -1
- package/dist/components/supportTicket/TicketReplyBox.js +29 -10
- package/dist/components/supportTicket/TicketReplyBox.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/engine/CompactRow.tsx +141 -22
- package/src/components/form/engine/CompactToolbar.tsx +85 -16
- package/src/components/form/engine/FormEngine.stories.tsx +25 -13
- package/src/components/form/engine/FormEngine.tsx +358 -77
- package/src/components/form/engine/FormEngineAppearance.stories.tsx +540 -0
- package/src/components/form/engine/FormEngineStickyHeaders.stories.tsx +5 -1
- package/src/components/form/engine/OptionFieldMessages.tsx +73 -2
- package/src/components/form/engine/_structuredData/SchemaDataView.tsx +17 -4
- package/src/components/form/engine/compactRowContext.ts +5 -0
- package/src/components/form/engine/compactRowStyles.ts +218 -38
- package/src/components/form/engine/compactToolbarContext.ts +3 -0
- package/src/components/form/engine/formAppearance.ts +78 -0
- package/src/components/form/engine/readFirst.ts +16 -3
- package/src/components/form/engine/rowFocus.ts +17 -6
- package/src/components/form/fields/ChoiceGroupHeading.tsx +38 -0
- package/src/components/form/fields/Field.tsx +6 -5
- package/src/components/form/fields/allowed-values/AllowedValues.tsx +7 -4
- package/src/components/form/fields/radio-group/RadioGroup.tsx +13 -7
- package/src/components/form/index.tsx +1 -0
- package/src/components/supportTicket/TicketHeader.tsx +2 -1
- package/src/components/supportTicket/TicketReplyBox.stories.tsx +17 -2
- package/src/components/supportTicket/TicketReplyBox.tsx +27 -5
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// - `ConnectionManagement` per-item actions — dropped (actions omitted).
|
|
9
9
|
// - `Select` → reqraft `SelectFormField` (`items` instead of `defaultItems`,
|
|
10
10
|
// single-arg `onChange`; `type`/`closeCollectionOnUnMount` not forwarded).
|
|
11
|
-
import { ReqoreCheckbox, ReqoreControlGroup
|
|
11
|
+
import { ReqoreCheckbox, ReqoreControlGroup } from '@qoretechnologies/reqore';
|
|
12
12
|
import { IReqoreButtonProps } from '@qoretechnologies/reqore/dist/components/Button';
|
|
13
13
|
import { IQorusAllowedValue, TQorusType } from '@qoretechnologies/ts-toolkit';
|
|
14
14
|
import { size as count, isEqual } from 'lodash';
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '../select/SelectCollection';
|
|
21
21
|
import { ISelectFormFieldItem, SelectFormField as Select } from '../select/Select';
|
|
22
22
|
import { useAllowedValueAvailability } from '../../engine/OptionFieldMessages';
|
|
23
|
+
import { ChoiceGroupHeading, useSelectedChoiceIntent } from '../ChoiceGroupHeading';
|
|
23
24
|
import type { IReqraftAllowedValue } from '../Field';
|
|
24
25
|
|
|
25
26
|
export interface IFieldAllowedValuesProps extends Pick<
|
|
@@ -97,13 +98,15 @@ export const FieldAllowedValuesCheckGroup = memo(
|
|
|
97
98
|
*/
|
|
98
99
|
label?: string;
|
|
99
100
|
}) => {
|
|
101
|
+
const selectedChoiceIntent = useSelectedChoiceIntent();
|
|
102
|
+
|
|
100
103
|
return (
|
|
101
104
|
<ReqoreControlGroup vertical size={rest.size || 'small'} gapSize='tiny'>
|
|
102
|
-
<
|
|
105
|
+
<ChoiceGroupHeading>
|
|
103
106
|
{label ? `${label}:`
|
|
104
107
|
: multiSelect ? 'Select one or more:'
|
|
105
108
|
: 'Select one:'}
|
|
106
|
-
</
|
|
109
|
+
</ChoiceGroupHeading>
|
|
107
110
|
{items?.map((item) => {
|
|
108
111
|
const unavailable = getSelectItemUnavailability(item);
|
|
109
112
|
|
|
@@ -134,7 +137,7 @@ export const FieldAllowedValuesCheckGroup = memo(
|
|
|
134
137
|
which keeps the pointer events the tooltip is read through.
|
|
135
138
|
It does not withhold `onClick` — the handler below does. */
|
|
136
139
|
readOnly={rest.readOnly || !!unavailable}
|
|
137
|
-
intent={item.value === value
|
|
140
|
+
intent={selectedChoiceIntent(item.value === value)}
|
|
138
141
|
// `isEqual`, and only once there is a value to match. The single
|
|
139
142
|
// -select branch compared JSON.stringify(value) with
|
|
140
143
|
// JSON.stringify(item.value), and JSON.stringify(undefined) is
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReqoreRadioGroup } from '@qoretechnologies/reqore';
|
|
2
2
|
import { IReqoreRadioGroupProps } from '@qoretechnologies/reqore/dist/components/RadioGroup';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
|
+
import { useIsCalmForm } from '../../engine/formAppearance';
|
|
4
5
|
|
|
5
6
|
export interface IRadioGroupFormFieldProps
|
|
6
7
|
extends Omit<IReqoreRadioGroupProps, 'onChange' | 'onSelectClick' | 'selected'> {
|
|
@@ -16,20 +17,25 @@ export const RadioGroupFormField = ({
|
|
|
16
17
|
value,
|
|
17
18
|
...rest
|
|
18
19
|
}: IRadioGroupFormFieldProps) => {
|
|
20
|
+
const calm = useIsCalmForm();
|
|
19
21
|
const items: IReqoreRadioGroupProps['items'] = useMemo(
|
|
20
22
|
() =>
|
|
21
23
|
_items.map((item) => ({
|
|
22
24
|
margin: 'right',
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
// Calm: an option's name as written — a choice is read, not shouted.
|
|
26
|
+
labelEffect:
|
|
27
|
+
calm ?
|
|
28
|
+
{ textSize: 'small' }
|
|
29
|
+
: {
|
|
30
|
+
spaced: 1,
|
|
31
|
+
weight: 'bold',
|
|
32
|
+
uppercase: true,
|
|
33
|
+
textSize: 'small',
|
|
34
|
+
},
|
|
29
35
|
...item,
|
|
30
36
|
disabled: disabled || item.disabled,
|
|
31
37
|
})),
|
|
32
|
-
[_items]
|
|
38
|
+
[_items, calm]
|
|
33
39
|
);
|
|
34
40
|
|
|
35
41
|
return (
|
|
@@ -24,6 +24,7 @@ export * from './fields/string/String';
|
|
|
24
24
|
export * from './fields/template/ExampleValueModal';
|
|
25
25
|
export * from './fields/template/TemplateField';
|
|
26
26
|
export * from './engine/FormEngine';
|
|
27
|
+
export * from './engine/formAppearance';
|
|
27
28
|
export * from './engine/FormFieldsSkeleton';
|
|
28
29
|
export * from './engine/optionActions';
|
|
29
30
|
export * from './engine/rendererTypes';
|
|
@@ -201,7 +201,8 @@ export const TicketHeader = ({
|
|
|
201
201
|
and the strip would no longer line up with them. */
|
|
202
202
|
rowPadding='tiny'
|
|
203
203
|
labelWidth={LABEL_WIDTH}
|
|
204
|
-
uppercaseLabels
|
|
204
|
+
/* The labels' case is the theme's (`theme.uppercaseLabels`): an app that sets its
|
|
205
|
+
labels in sentence case gets "Opened by", not "OPENED BY". */
|
|
205
206
|
flat
|
|
206
207
|
transparent
|
|
207
208
|
padded={false}
|
|
@@ -16,6 +16,19 @@ const meta = {
|
|
|
16
16
|
export default meta;
|
|
17
17
|
type Story = StoryObj<typeof meta>;
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The reply is sent with the white primary, never the Qonsole purple: a ticket reply is not a
|
|
21
|
+
* hand-off to Qonsole (instruction-files decision 002). Read from the drawn button, so a theme
|
|
22
|
+
* or a default that brings the purple back fails here.
|
|
23
|
+
*/
|
|
24
|
+
const expectWhiteSend = async (canvasElement: HTMLElement) => {
|
|
25
|
+
const send = within(canvasElement).getByText('Send reply').closest('button')!;
|
|
26
|
+
await waitFor(() => {
|
|
27
|
+
const [r, g, b] = getComputedStyle(send).backgroundColor.match(/\d+/g)!.map(Number);
|
|
28
|
+
expect(Math.min(r, g, b)).toBeGreaterThan(200);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
19
32
|
/**
|
|
20
33
|
* The customer composer, plain-editor variant (used here for a deterministic
|
|
21
34
|
* type→send test): an attach button (no extra menu → a plain button, not a
|
|
@@ -27,7 +40,7 @@ export const Default: Story = {
|
|
|
27
40
|
docs: {
|
|
28
41
|
description: {
|
|
29
42
|
story:
|
|
30
|
-
"Renders the customer composer's plain-editor variant — an attach button and Send, no internal-note toggle; typing a reply enables Send, which calls onSend with the body and internal: false.",
|
|
43
|
+
"Renders the customer composer's plain-editor variant — an attach button and Send, no internal-note toggle; typing a reply enables Send — the white primary, not the Qonsole purple — which calls onSend with the body and internal: false.",
|
|
31
44
|
},
|
|
32
45
|
},
|
|
33
46
|
},
|
|
@@ -39,6 +52,7 @@ export const Default: Story = {
|
|
|
39
52
|
await expect(canvas.queryByText('Internal note')).not.toBeInTheDocument();
|
|
40
53
|
|
|
41
54
|
await userEvent.type(textarea!, 'Here is my reply');
|
|
55
|
+
await expectWhiteSend(canvasElement);
|
|
42
56
|
await userEvent.click(canvas.getByText('Send reply'));
|
|
43
57
|
await waitFor(() =>
|
|
44
58
|
expect(args.onSend).toHaveBeenCalledWith(
|
|
@@ -59,7 +73,7 @@ export const StaffWithInternalNote: Story = {
|
|
|
59
73
|
docs: {
|
|
60
74
|
description: {
|
|
61
75
|
story:
|
|
62
|
-
"Renders the staff composer with a split send button — the primary action posts a public reply, while the caret opens 'Add internal note', which sends with internal: true.",
|
|
76
|
+
"Renders the staff composer with a split send button — the primary action (white, not the Qonsole purple) posts a public reply, while the caret opens 'Add internal note', which sends with internal: true.",
|
|
63
77
|
},
|
|
64
78
|
},
|
|
65
79
|
},
|
|
@@ -72,6 +86,7 @@ export const StaffWithInternalNote: Story = {
|
|
|
72
86
|
|
|
73
87
|
const textarea = canvasElement.querySelector('textarea');
|
|
74
88
|
await userEvent.type(textarea!, 'internal context');
|
|
89
|
+
await expectWhiteSend(canvasElement);
|
|
75
90
|
|
|
76
91
|
// "Add internal note" lives behind the split-send caret
|
|
77
92
|
const caret = canvasElement.querySelector('.ticket-send-more');
|
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
import type { TReqoreDropdownItems } from '@qoretechnologies/reqore/dist/components/Dropdown/list';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Composer,
|
|
5
|
+
IComposerProps,
|
|
6
|
+
IComposerSendAction,
|
|
7
|
+
TComposerEditor,
|
|
8
|
+
} from '../composer/Composer';
|
|
4
9
|
import { fileToAttachment as defaultFileToAttachment } from './fileToAttachment';
|
|
5
10
|
import { IAttachmentUpload } from './meta';
|
|
6
11
|
|
|
12
|
+
/**
|
|
13
|
+
* A ticket reply is not a hand-off to Qonsole, so it does not wear Qonsole's look: no purple
|
|
14
|
+
* bar, no purple send (instruction-files decision 002 — a purple button means "this hands the
|
|
15
|
+
* work to Qonsole / AI" and nothing else). The bar keeps the composer's shape with the theme's
|
|
16
|
+
* own neutral edge (its `main`, a step lighter — how Reqore draws its dividers), and sending
|
|
17
|
+
* the reply is the surface's one primary action: white.
|
|
18
|
+
*/
|
|
19
|
+
const REPLY_BOX_EFFECT: IComposerProps['effect'] = {
|
|
20
|
+
gradient: { direction: 'to bottom right', colors: 'main:lighten:3' },
|
|
21
|
+
};
|
|
22
|
+
const REPLY_SEND_STYLE: Pick<IComposerSendAction, 'intent' | 'minimal'> = {
|
|
23
|
+
intent: 'white',
|
|
24
|
+
minimal: false,
|
|
25
|
+
};
|
|
26
|
+
|
|
7
27
|
/**
|
|
8
28
|
* The `items` shape ReqoreDropdown accepts. Named, not derived: `ReqoreDropdown`
|
|
9
29
|
* is a generic component, and `ComponentProps` of a generic resolves to `{}`
|
|
@@ -96,16 +116,15 @@ export const TicketReplyBox = ({
|
|
|
96
116
|
: 'Send reply';
|
|
97
117
|
|
|
98
118
|
// Staff surface splits the send button; customer surface is a single "Send reply".
|
|
99
|
-
// Both
|
|
100
|
-
//
|
|
119
|
+
// Both send the reply as the white primary (`REPLY_SEND_STYLE`); the internal note
|
|
120
|
+
// stays amber (`warning`) so it can't be mistaken for a public reply.
|
|
101
121
|
const sendActions: IComposerSendAction[] | undefined = allowInternalNote
|
|
102
122
|
? [
|
|
103
123
|
{
|
|
104
124
|
id: 'reply',
|
|
105
125
|
label: labelFor(false),
|
|
106
126
|
icon: 'SendPlane2Line',
|
|
107
|
-
|
|
108
|
-
customTheme: { main: 'custom1' },
|
|
127
|
+
...REPLY_SEND_STYLE,
|
|
109
128
|
},
|
|
110
129
|
{
|
|
111
130
|
id: 'internal',
|
|
@@ -139,7 +158,10 @@ export const TicketReplyBox = ({
|
|
|
139
158
|
disabledReason={disabledReason}
|
|
140
159
|
onSend={handleSend}
|
|
141
160
|
sendLabel={labelFor(false)}
|
|
161
|
+
sendIntent={REPLY_SEND_STYLE.intent}
|
|
162
|
+
sendMinimal={REPLY_SEND_STYLE.minimal}
|
|
142
163
|
sendActions={sendActions}
|
|
164
|
+
effect={REPLY_BOX_EFFECT}
|
|
143
165
|
sendMenuClassName='ticket-send-more'
|
|
144
166
|
attachMenuItems={attachMenuItems}
|
|
145
167
|
footerActions={footerActions}
|