@evergis/react 4.0.167 → 4.0.168
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/Dashboard/componentTypes.d.ts +3 -4
- package/dist/components/Dashboard/components/ContainerButton/index.d.ts +4 -0
- package/dist/components/Dashboard/containers/VoteContainer/components/VoteScreen.d.ts +2 -2
- package/dist/components/Dashboard/containers/VoteContainer/types.d.ts +10 -3
- package/dist/components/Dashboard/utils/getButtonSlot.d.ts +4 -0
- package/dist/index.js +45 -31
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +45 -31
- package/dist/react.esm.js.map +1 -1
- package/package.json +2 -2
|
@@ -164,9 +164,8 @@ export interface ElementUploaderProps extends Omit<ContainerProps, "elementConfi
|
|
|
164
164
|
*/
|
|
165
165
|
export type ContainerBoxOptions = Pick<ConfigOptions, "width" | "height" | "overflow">;
|
|
166
166
|
export type AddFeatureContainerOptions = Record<string, never>;
|
|
167
|
-
export type AddFeatureButtonOptions = Pick<ConfigOptions, "
|
|
168
|
-
export interface AddFeatureButtonChild extends Omit<
|
|
169
|
-
type?: "button";
|
|
167
|
+
export type AddFeatureButtonOptions = Pick<ConfigOptions, "layerName" | "geometryType"> & ElementButtonOptions;
|
|
168
|
+
export interface AddFeatureButtonChild extends Omit<ElementButtonConfig, "options"> {
|
|
170
169
|
options?: AddFeatureButtonOptions;
|
|
171
170
|
}
|
|
172
171
|
export interface AddFeatureContainerConfig extends Omit<ConfigContainerChild, "options" | "templateName" | "children"> {
|
|
@@ -356,7 +355,7 @@ export interface EditAttachmentContainerConfig extends Omit<ConfigContainerChild
|
|
|
356
355
|
export interface EditAttachmentContainerProps extends Omit<ContainerProps, "elementConfig"> {
|
|
357
356
|
elementConfig?: EditAttachmentContainerConfig;
|
|
358
357
|
}
|
|
359
|
-
export type ExportPdfContainerOptions =
|
|
358
|
+
export type ExportPdfContainerOptions = Record<string, never>;
|
|
360
359
|
export interface ExportPdfContainerConfig extends Omit<ConfigContainerChild, "options" | "templateName"> {
|
|
361
360
|
templateName?: ContainerTemplate.ExportPdf;
|
|
362
361
|
options?: ExportPdfContainerOptions;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
import { VoteScreenProps } from '../types';
|
|
2
|
+
import { VoteButtonProps, VoteScreenProps } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Тело контейнера: выбирает экран по вью-модели голосования.
|
|
5
5
|
*
|
|
6
6
|
* Живёт отдельно от `VoteContainer`, потому что тот отвечает за корень контейнера — размеры,
|
|
7
7
|
* фон и заголовок — и не должен раздуваться ветвлением по состояниям.
|
|
8
8
|
*/
|
|
9
|
-
export declare const VoteScreen: FC<VoteScreenProps>;
|
|
9
|
+
export declare const VoteScreen: FC<VoteScreenProps & VoteButtonProps>;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { VoteContainerOptions } from '../../componentTypes';
|
|
1
|
+
import { ElementButtonConfig, VoteContainerOptions } from '../../componentTypes';
|
|
2
|
+
import { WidgetType } from '../../types';
|
|
3
|
+
export type VoteButtonSlotId = "submitButton" | "createButton" | "saveButton" | "deleteButton";
|
|
4
|
+
export type VoteButtonConfigs = Partial<Record<VoteButtonSlotId, ElementButtonConfig>>;
|
|
5
|
+
export interface VoteButtonProps {
|
|
6
|
+
type?: WidgetType;
|
|
7
|
+
buttonConfigs: VoteButtonConfigs;
|
|
8
|
+
}
|
|
2
9
|
/** Экран, который показывает контейнер голосования. */
|
|
3
10
|
export type VoteScreen = "loading" | "create" | "voting" | "voted" | "unauthenticated";
|
|
4
11
|
export interface VoteCategory {
|
|
@@ -40,7 +47,7 @@ export interface VoteFormVariant {
|
|
|
40
47
|
* к данным отношения не имеют, а `Required<VoteContainerOptions>` потребовал бы и их.
|
|
41
48
|
*/
|
|
42
49
|
export type VoteDataSources = Required<Pick<VoteContainerOptions, "categoryDataSource" | "questionDataSource" | "variantDataSource" | "answerDataSource">>;
|
|
43
|
-
export interface VoteCreateFormProps {
|
|
50
|
+
export interface VoteCreateFormProps extends VoteButtonProps {
|
|
44
51
|
categories: VoteCategory[];
|
|
45
52
|
initialValues?: VoteFormValues;
|
|
46
53
|
isEditing: boolean;
|
|
@@ -50,7 +57,7 @@ export interface VoteCreateFormProps {
|
|
|
50
57
|
onDelete?: () => void;
|
|
51
58
|
onCancel?: () => void;
|
|
52
59
|
}
|
|
53
|
-
export interface VoteResultsProps {
|
|
60
|
+
export interface VoteResultsProps extends VoteButtonProps {
|
|
54
61
|
question: VoteQuestion;
|
|
55
62
|
category?: VoteCategory;
|
|
56
63
|
results: VoteVariantResult[];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ElementButtonConfig } from '../componentTypes';
|
|
2
|
+
import { ConfigContainerChild } from '../types';
|
|
3
|
+
/** Слот кнопки существует только при совпадении id и явном type: "button". */
|
|
4
|
+
export declare const getButtonSlot: (children: ConfigContainerChild[] | undefined, id: string) => ElementButtonConfig | undefined;
|
package/dist/index.js
CHANGED
|
@@ -5154,7 +5154,7 @@ const FeatureControls = styled(uilibGl.Flex).withConfig({ displayName: "FeatureC
|
|
|
5154
5154
|
const FiltersContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "FiltersContainerWrapper", componentId: "sc-1a6ru74" }) `
|
|
5155
5155
|
flex-direction: column;
|
|
5156
5156
|
padding: ${({ $padding }) => $padding ?? `${DEFAULT_FILTER_PADDING}px`};
|
|
5157
|
-
background
|
|
5157
|
+
background: ${({ $bgColor, $fontColor, theme: { palette } }) => $bgColor || ($fontColor ? transparentizeColor($fontColor, 6) : palette.element)};
|
|
5158
5158
|
border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
|
|
5159
5159
|
|
|
5160
5160
|
${uilibGl.DropdownField}, input {
|
|
@@ -8948,7 +8948,7 @@ const POLL_SUBTASK_INTERVAL_MS = 500;
|
|
|
8948
8948
|
const POLL_SUBTASK_TIMEOUT_MS = 15_000;
|
|
8949
8949
|
|
|
8950
8950
|
const StatusBadge = styled(uilibGl.Chip).withConfig({ displayName: "StatusBadge", componentId: "sc-1xmfl10" }) `
|
|
8951
|
-
background
|
|
8951
|
+
background: ${({ bgColor }) => bgColor};
|
|
8952
8952
|
color: ${({ theme }) => theme.palette.iconContrast};
|
|
8953
8953
|
`;
|
|
8954
8954
|
|
|
@@ -11293,7 +11293,7 @@ const FilterChip = styled.div.withConfig({ displayName: "FilterChip", componentI
|
|
|
11293
11293
|
padding: 0.3125rem 0.5rem;
|
|
11294
11294
|
height: 1.5rem;
|
|
11295
11295
|
border-radius: 0.25rem;
|
|
11296
|
-
background
|
|
11296
|
+
background: ${({ $isActive, $bgColor, theme }) => $bgColor
|
|
11297
11297
|
? $bgColor
|
|
11298
11298
|
: $isActive
|
|
11299
11299
|
? theme.palette?.primary
|
|
@@ -11313,7 +11313,7 @@ const FilterChip = styled.div.withConfig({ displayName: "FilterChip", componentI
|
|
|
11313
11313
|
box-sizing: border-box;
|
|
11314
11314
|
|
|
11315
11315
|
&:hover {
|
|
11316
|
-
background
|
|
11316
|
+
background: ${({ $isActive, $bgColor, theme }) => $isActive
|
|
11317
11317
|
? $bgColor || 'inherit'
|
|
11318
11318
|
: $bgColor || theme.palette?.elementDark};
|
|
11319
11319
|
}
|
|
@@ -14558,12 +14558,21 @@ const ContainerBackground = React.memo(({ elementConfig, renderElement }) => {
|
|
|
14558
14558
|
return (jsxRuntime.jsx(ContainerBackgroundLayer, { "$outflow": elementConfig?.options?.outflow, children: renderElement({ id: BG_IMAGE_SLOT_ID, wrap: false }) }));
|
|
14559
14559
|
});
|
|
14560
14560
|
|
|
14561
|
-
|
|
14561
|
+
/** Кнопка нативного действия контейнера со стандартными подстановками дочернего конфига. */
|
|
14562
|
+
const ContainerButton = React.memo(({ type = exports.WidgetType.Dashboard, elementConfig, ...props }) => {
|
|
14563
|
+
const sources = useConfigStringSources(type);
|
|
14564
|
+
const node = useActionNode();
|
|
14565
|
+
const attributes = props.attributes ?? node.attributes ?? sources.attributes;
|
|
14566
|
+
const resolvedConfig = React.useMemo(() => resolveElementStrings(elementConfig, { ...sources, attributes }), [elementConfig, sources, attributes]);
|
|
14567
|
+
return jsxRuntime.jsx(ElementButton, { ...props, type: type, attributes: attributes, elementConfig: resolvedConfig });
|
|
14568
|
+
});
|
|
14569
|
+
|
|
14570
|
+
const AddFeatureContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
14562
14571
|
const { id, children, style } = elementConfig || {};
|
|
14563
14572
|
const bgHost = useBgImageHost(elementConfig);
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
.map((
|
|
14573
|
+
const handleAddFeature = React.useCallback(() => undefined, []);
|
|
14574
|
+
return (jsxRuntime.jsxs(Container, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), children?.filter(({ type: childType }) => childType === "button")
|
|
14575
|
+
.map((button, index) => (jsxRuntime.jsx(ContainerButton, { type: type, elementConfig: button, onClick: handleAddFeature }, button.id ?? index)))] }));
|
|
14567
14576
|
});
|
|
14568
14577
|
|
|
14569
14578
|
/**
|
|
@@ -16497,7 +16506,7 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ disp
|
|
|
16497
16506
|
* иначе фон тонируется цветом иконки, а без неё — цветом текста (colorAttribute/fontColor);
|
|
16498
16507
|
* если не задан ни один цвет, остаётся токен темы.
|
|
16499
16508
|
*/
|
|
16500
|
-
background
|
|
16509
|
+
background: ${({ $bgColor, $iconColor, $color, theme: { palette } }) => $bgColor || tintedBackground($iconColor || $color) || palette.element};
|
|
16501
16510
|
border-radius: ${({ theme: { borderRadius } }) => borderRadius.large};
|
|
16502
16511
|
flex-wrap: nowrap;
|
|
16503
16512
|
|
|
@@ -16568,11 +16577,6 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ disp
|
|
|
16568
16577
|
> * {
|
|
16569
16578
|
text-align: left;
|
|
16570
16579
|
}
|
|
16571
|
-
|
|
16572
|
-
/* Зазор наружу даёт обёртка иконки, здесь — отступ внутри её бокса. */
|
|
16573
|
-
span[kind] {
|
|
16574
|
-
margin-right: 0.5rem;
|
|
16575
|
-
}
|
|
16576
16580
|
|
|
16577
16581
|
${ContainerValue} {
|
|
16578
16582
|
width: auto;
|
|
@@ -17286,7 +17290,7 @@ const TabContainer = styled.a.withConfig({ displayName: "TabContainer", componen
|
|
|
17286
17290
|
justify-content: center;
|
|
17287
17291
|
flex-wrap: nowrap;
|
|
17288
17292
|
padding: ${({ onlyIcon }) => (onlyIcon ? 1 : 0.5)}rem 1rem;
|
|
17289
|
-
background
|
|
17293
|
+
background: ${({ active, bgColor, theme: { palette } }) => active ? bgColor || palette.primary : palette.element};
|
|
17290
17294
|
border-radius: ${({ column, radius, theme: { borderRadius } }) => radius ? `${radius}px` : column ? borderRadius.medium : borderRadius.xLarge};
|
|
17291
17295
|
text-decoration: none;
|
|
17292
17296
|
|
|
@@ -17752,22 +17756,22 @@ const useVoteForm = (initialValues) => {
|
|
|
17752
17756
|
};
|
|
17753
17757
|
};
|
|
17754
17758
|
|
|
17755
|
-
const VoteCreateForm = ({ categories, initialValues, isEditing, canDelete, submitting, onSubmit, onDelete, onCancel, }) => {
|
|
17759
|
+
const VoteCreateForm = ({ type, buttonConfigs, categories, initialValues, isEditing, canDelete, submitting, onSubmit, onDelete, onCancel, }) => {
|
|
17756
17760
|
const { t } = useGlobalContext();
|
|
17757
17761
|
const form = useVoteForm(initialValues);
|
|
17758
17762
|
const { categoryId, setCategoryId, text, setText, multiSelect, setMultiSelect, variants, addVariant, removeVariant, draft, setDraft, isValid, values, } = form;
|
|
17759
17763
|
const categoryOptions = React.useMemo(() => categories.map(({ id, name }) => ({ text: name, value: id })), [categories]);
|
|
17764
|
+
const submitButton = React.useMemo(() => isEditing ? buttonConfigs.saveButton : buttonConfigs.createButton, [buttonConfigs, isEditing]);
|
|
17765
|
+
const handleSubmit = React.useCallback(() => onSubmit(values), [onSubmit, values]);
|
|
17760
17766
|
return (jsxRuntime.jsxs(VoteWrapper, { children: [!isEditing && jsxRuntime.jsx(VoteHeading, { children: t("vote.newVote", { ns: VOTE_NS, defaultValue: "Новое голосование" }) }), jsxRuntime.jsx(uilibGl.Dropdown, { zIndex: 110000, label: t("vote.category", { ns: VOTE_NS, defaultValue: "Категория" }), width: "100%", placeholder: t("vote.categoryPlaceholder", { ns: VOTE_NS, defaultValue: "Выберите категорию" }), options: categoryOptions, value: categoryId, onChange: items => setCategoryId(String(items[0]?.value ?? "")) }), jsxRuntime.jsx(uilibGl.Input, { label: t("vote.question", { ns: VOTE_NS, defaultValue: "Вопрос" }), width: "100%", placeholder: t("vote.questionPlaceholder", { ns: VOTE_NS, defaultValue: "Текст вопроса" }), value: text, onChange: ({ target }) => setText(target.value) }), jsxRuntime.jsx(VoteSectionLabel, { children: t("vote.variants", { ns: VOTE_NS, defaultValue: "Варианты ответов" }) }), !!variants.length && (jsxRuntime.jsx(VoteChipList, { children: variants.map(({ text: variantText }, index) => (jsxRuntime.jsxs(VoteChip, { children: [jsxRuntime.jsx(VoteVariantText, { children: variantText }), jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", onClick: () => removeVariant(index) })] }, `${variantText}:${index}`))) })), jsxRuntime.jsx(uilibGl.Input, { width: "100%", placeholder: t("vote.variantPlaceholder", { ns: VOTE_NS, defaultValue: "Введите вариант и нажмите Enter" }), value: draft, onChange: ({ target }) => setDraft(target.value), onKeyDown: event => {
|
|
17761
17767
|
if (event.key === "Enter") {
|
|
17762
17768
|
event.preventDefault();
|
|
17763
17769
|
addVariant();
|
|
17764
17770
|
}
|
|
17765
|
-
} }), jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", justifyContent: "space-between", children: [jsxRuntime.jsx(VoteSectionLabel, { children: t("vote.multiSelect", { ns: VOTE_NS, defaultValue: "Множественный выбор" }) }), jsxRuntime.jsx(uilibGl.Switch, { checked: multiSelect, onChange: () => setMultiSelect(prev => !prev) })] }), jsxRuntime.jsx(
|
|
17766
|
-
? t("vote.save", { ns: VOTE_NS, defaultValue: "Сохранить" })
|
|
17767
|
-
: t("vote.create", { ns: VOTE_NS, defaultValue: "Создать голосование" }) }), !isValid && (jsxRuntime.jsx(VoteHint, { children: t("vote.formHint", {
|
|
17771
|
+
} }), jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", justifyContent: "space-between", children: [jsxRuntime.jsx(VoteSectionLabel, { children: t("vote.multiSelect", { ns: VOTE_NS, defaultValue: "Множественный выбор" }) }), jsxRuntime.jsx(uilibGl.Switch, { checked: multiSelect, onChange: () => setMultiSelect(prev => !prev) })] }), submitButton && (jsxRuntime.jsx(ContainerButton, { type: type, elementConfig: submitButton, disabled: !isValid || submitting, onClick: handleSubmit })), !isValid && (jsxRuntime.jsx(VoteHint, { children: t("vote.formHint", {
|
|
17768
17772
|
ns: VOTE_NS,
|
|
17769
17773
|
defaultValue: "Нужны категория, вопрос и минимум два варианта ответа",
|
|
17770
|
-
}) })), isEditing && (jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", justifyContent: "space-between", children: [onCancel && (jsxRuntime.jsx(VoteEditLink, { onClick: onCancel, children: t("vote.cancel", { ns: VOTE_NS, defaultValue: "Отмена" }) })), canDelete && onDelete && (jsxRuntime.jsx(
|
|
17774
|
+
}) })), isEditing && (jsxRuntime.jsxs(uilibGl.Flex, { alignItems: "center", justifyContent: "space-between", children: [onCancel && (jsxRuntime.jsx(VoteEditLink, { onClick: onCancel, children: t("vote.cancel", { ns: VOTE_NS, defaultValue: "Отмена" }) })), canDelete && onDelete && buttonConfigs.deleteButton && (jsxRuntime.jsx(ContainerButton, { type: type, elementConfig: buttonConfigs.deleteButton, disabled: submitting, onClick: onDelete }))] }))] }));
|
|
17771
17775
|
};
|
|
17772
17776
|
|
|
17773
17777
|
/** Блок «Поделиться в соцсетях» — пока только вёрстка, без рабочих ссылок. */
|
|
@@ -17776,7 +17780,7 @@ const VoteShare = () => {
|
|
|
17776
17780
|
return (jsxRuntime.jsxs(VoteShareBlock, { children: [jsxRuntime.jsx(VoteSectionLabel, { children: t("vote.share", { ns: VOTE_NS, defaultValue: "Поделиться в соцсетях" }) }), jsxRuntime.jsx(VoteShareChips, { children: VOTE_SOCIALS.map(name => (jsxRuntime.jsx(VoteShareChip, { children: name }, name))) })] }));
|
|
17777
17781
|
};
|
|
17778
17782
|
|
|
17779
|
-
const VoteResults = ({ question, category, results, screen, isOwner, hasAnswers, submitting, onSubmit, onEdit, }) => {
|
|
17783
|
+
const VoteResults = ({ type, buttonConfigs, question, category, results, screen, isOwner, hasAnswers, submitting, onSubmit, onEdit, }) => {
|
|
17780
17784
|
const { t } = useGlobalContext();
|
|
17781
17785
|
const [selected, setSelected] = React.useState([]);
|
|
17782
17786
|
const showControls = screen === "voting";
|
|
@@ -17790,8 +17794,9 @@ const VoteResults = ({ question, category, results, screen, isOwner, hasAnswers,
|
|
|
17790
17794
|
});
|
|
17791
17795
|
}, [question.multiSelect]);
|
|
17792
17796
|
const canSubmit = React.useMemo(() => selected.length > 0 && !submitting, [selected.length, submitting]);
|
|
17797
|
+
const handleSubmit = React.useCallback(() => onSubmit(selected), [onSubmit, selected]);
|
|
17793
17798
|
return (jsxRuntime.jsxs(VoteWrapper, { children: [category && jsxRuntime.jsx(VoteCategoryLabel, { children: category.name }), jsxRuntime.jsx(VoteQuestionText, { children: question.text }), jsxRuntime.jsx(VoteVariantList, { column: true, value: selected[0] ?? "", children: results.map(({ id, text, count, percent }) => (jsxRuntime.jsxs(VoteVariantRow, { children: [jsxRuntime.jsxs(VoteVariantHead, { children: [showControls &&
|
|
17794
|
-
(question.multiSelect ? (jsxRuntime.jsx(uilibGl.Checkbox, { checked: selected.includes(id), onChange: () => toggle(id) })) : (jsxRuntime.jsx(uilibGl.Radio, { value: id, checked: selected.includes(id), onChange: () => toggle(id) }))), jsxRuntime.jsx(VoteVariantText, { children: text }), jsxRuntime.jsx(VoteVariantCount, { children: count })] }), jsxRuntime.jsx(uilibGl.LinearProgress, { done: percent })] }, id))) }), screen === "unauthenticated" && (jsxRuntime.jsx(VoteHint, { children: t("vote.authHint", { ns: VOTE_NS, defaultValue: "Чтобы проголосовать, пожалуйста, авторизуйтесь" }) })), screen === "voted" && (jsxRuntime.jsxs(VoteAcceptedBadge, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: "success" }), t("vote.accepted", { ns: VOTE_NS, defaultValue: "Ваш ответ принят" })] })), showControls && (jsxRuntime.jsx(
|
|
17799
|
+
(question.multiSelect ? (jsxRuntime.jsx(uilibGl.Checkbox, { checked: selected.includes(id), onChange: () => toggle(id) })) : (jsxRuntime.jsx(uilibGl.Radio, { value: id, checked: selected.includes(id), onChange: () => toggle(id) }))), jsxRuntime.jsx(VoteVariantText, { children: text }), jsxRuntime.jsx(VoteVariantCount, { children: count })] }), jsxRuntime.jsx(uilibGl.LinearProgress, { done: percent })] }, id))) }), screen === "unauthenticated" && (jsxRuntime.jsx(VoteHint, { children: t("vote.authHint", { ns: VOTE_NS, defaultValue: "Чтобы проголосовать, пожалуйста, авторизуйтесь" }) })), screen === "voted" && (jsxRuntime.jsxs(VoteAcceptedBadge, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: "success" }), t("vote.accepted", { ns: VOTE_NS, defaultValue: "Ваш ответ принят" })] })), showControls && buttonConfigs.submitButton && (jsxRuntime.jsx(ContainerButton, { type: type, elementConfig: buttonConfigs.submitButton, disabled: !canSubmit, onClick: handleSubmit })), canEdit && onEdit && (jsxRuntime.jsx(uilibGl.Flex, { children: jsxRuntime.jsx(VoteEditLink, { onClick: onEdit, children: t("vote.edit", { ns: VOTE_NS, defaultValue: "Редактировать" }) }) })), showShare && jsxRuntime.jsx(VoteShare, {})] }));
|
|
17795
17800
|
};
|
|
17796
17801
|
|
|
17797
17802
|
/**
|
|
@@ -17800,7 +17805,7 @@ const VoteResults = ({ question, category, results, screen, isOwner, hasAnswers,
|
|
|
17800
17805
|
* Живёт отдельно от `VoteContainer`, потому что тот отвечает за корень контейнера — размеры,
|
|
17801
17806
|
* фон и заголовок — и не должен раздуваться ветвлением по состояниям.
|
|
17802
17807
|
*/
|
|
17803
|
-
const VoteScreen = ({ screen, categories, question, category, results, totalVotes, isOwner, hasAnswers, isEditing, setIsEditing, editInitialValues, submitting, createVote, submitAnswer, editVote, deleteVote, }) => {
|
|
17808
|
+
const VoteScreen = ({ type, buttonConfigs, screen, categories, question, category, results, totalVotes, isOwner, hasAnswers, isEditing, setIsEditing, editInitialValues, submitting, createVote, submitAnswer, editVote, deleteVote, }) => {
|
|
17804
17809
|
const handleCreate = React.useCallback((values) => void createVote(values), [createVote]);
|
|
17805
17810
|
const handleEdit = React.useCallback((values) => void editVote(values).then(() => setIsEditing(false)), [editVote, setIsEditing]);
|
|
17806
17811
|
const handleDelete = React.useCallback(() => void deleteVote().then(() => setIsEditing(false)), [deleteVote, setIsEditing]);
|
|
@@ -17810,14 +17815,14 @@ const VoteScreen = ({ screen, categories, question, category, results, totalVote
|
|
|
17810
17815
|
if (screen === "loading")
|
|
17811
17816
|
return jsxRuntime.jsx(ContainerLoading, {});
|
|
17812
17817
|
if (isEditing && question) {
|
|
17813
|
-
return (jsxRuntime.jsx(VoteCreateForm, { categories: categories, initialValues: editInitialValues, isEditing: true, canDelete: !hasAnswers, submitting: submitting, onSubmit: handleEdit, onDelete: handleDelete, onCancel: handleCancel }));
|
|
17818
|
+
return (jsxRuntime.jsx(VoteCreateForm, { type: type, buttonConfigs: buttonConfigs, categories: categories, initialValues: editInitialValues, isEditing: true, canDelete: !hasAnswers, submitting: submitting, onSubmit: handleEdit, onDelete: handleDelete, onCancel: handleCancel }));
|
|
17814
17819
|
}
|
|
17815
17820
|
if (screen === "create") {
|
|
17816
|
-
return (jsxRuntime.jsx(VoteCreateForm, { categories: categories, isEditing: false, canDelete: false, submitting: submitting, onSubmit: handleCreate }));
|
|
17821
|
+
return (jsxRuntime.jsx(VoteCreateForm, { type: type, buttonConfigs: buttonConfigs, categories: categories, isEditing: false, canDelete: false, submitting: submitting, onSubmit: handleCreate }));
|
|
17817
17822
|
}
|
|
17818
17823
|
if (!question)
|
|
17819
17824
|
return null;
|
|
17820
|
-
return (jsxRuntime.jsx(VoteResults, { question: question, category: category, results: results, totalVotes: totalVotes, screen: screen, isOwner: isOwner, hasAnswers: hasAnswers, submitting: submitting, onSubmit: handleSubmitAnswer, onEdit: handleEditOpen }));
|
|
17825
|
+
return (jsxRuntime.jsx(VoteResults, { type: type, buttonConfigs: buttonConfigs, question: question, category: category, results: results, totalVotes: totalVotes, screen: screen, isOwner: isOwner, hasAnswers: hasAnswers, submitting: submitting, onSubmit: handleSubmitAnswer, onEdit: handleEditOpen }));
|
|
17821
17826
|
};
|
|
17822
17827
|
|
|
17823
17828
|
/** Приводит значение атрибута к строке-идентификатору (id приходят числами/строками). */
|
|
@@ -18244,6 +18249,9 @@ const useVoteContainer = (elementConfig) => {
|
|
|
18244
18249
|
};
|
|
18245
18250
|
};
|
|
18246
18251
|
|
|
18252
|
+
/** Слот кнопки существует только при совпадении id и явном type: "button". */
|
|
18253
|
+
const getButtonSlot = (children, id) => children?.find((child) => child.id === id && child.type === "button");
|
|
18254
|
+
|
|
18247
18255
|
/**
|
|
18248
18256
|
* Контейнер «Голосование»: привязывает опрос к объекту карты через `attributeName`
|
|
18249
18257
|
* и показывает один из экранов — создание, голосование, после голосования
|
|
@@ -18255,6 +18263,13 @@ const useVoteContainer = (elementConfig) => {
|
|
|
18255
18263
|
const VoteContainer = React.memo(({ type, elementConfig, isVisible, renderElement }) => {
|
|
18256
18264
|
const { root, body } = useContainerRoot({ elementConfig });
|
|
18257
18265
|
const { configured, ...vote } = useVoteContainer(elementConfig);
|
|
18266
|
+
const children = elementConfig?.children;
|
|
18267
|
+
const buttonConfigs = React.useMemo(() => ({
|
|
18268
|
+
submitButton: getButtonSlot(children, "submitButton"),
|
|
18269
|
+
createButton: getButtonSlot(children, "createButton"),
|
|
18270
|
+
saveButton: getButtonSlot(children, "saveButton"),
|
|
18271
|
+
deleteButton: getButtonSlot(children, "deleteButton"),
|
|
18272
|
+
}), [children]);
|
|
18258
18273
|
// Без имени атрибута или хотя бы одного источника контейнеру не с чем работать. Ошибка вместо
|
|
18259
18274
|
// пустоты: молчаливый `null` выдавал бы опечатку в конфиге за «блока просто нет».
|
|
18260
18275
|
if (!configured) {
|
|
@@ -18264,7 +18279,7 @@ const VoteContainer = React.memo(({ type, elementConfig, isVisible, renderElemen
|
|
|
18264
18279
|
// в карточке в этом случае тоже не нужен, поэтому не рисуем и корень.
|
|
18265
18280
|
if (!vote.screen)
|
|
18266
18281
|
return null;
|
|
18267
|
-
return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, isColumn: true, children: jsxRuntime.jsx(VoteScreen, { ...vote, screen: vote.screen }) }))] }));
|
|
18282
|
+
return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, isColumn: true, children: jsxRuntime.jsx(VoteScreen, { ...vote, screen: vote.screen, type: type, buttonConfigs: buttonConfigs }) }))] }));
|
|
18268
18283
|
});
|
|
18269
18284
|
|
|
18270
18285
|
const ExpandableTitle = React.memo(({ elementConfig, type, renderElement }) => {
|
|
@@ -18880,12 +18895,11 @@ const ContainersGroupContainer = React.memo(props => {
|
|
|
18880
18895
|
});
|
|
18881
18896
|
|
|
18882
18897
|
const ExportPdfContainer = React.memo(({ type, elementConfig, renderElement }) => {
|
|
18883
|
-
const { t } = useGlobalContext();
|
|
18884
18898
|
const { loading, onExport } = useExportPdf(getRootElementId(type));
|
|
18885
|
-
const { id, style,
|
|
18886
|
-
const
|
|
18899
|
+
const { id, style, children } = elementConfig || {};
|
|
18900
|
+
const buttonConfig = React.useMemo(() => getButtonSlot(children, "button"), [children]);
|
|
18887
18901
|
const bgHost = useBgImageHost(elementConfig);
|
|
18888
|
-
return (jsxRuntime.jsxs(Container, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(
|
|
18902
|
+
return (jsxRuntime.jsxs(Container, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), buttonConfig && jsxRuntime.jsx(ContainerButton, { type: type, elementConfig: buttonConfig, disabled: loading, onClick: onExport })] }));
|
|
18889
18903
|
});
|
|
18890
18904
|
|
|
18891
18905
|
exports.ThemeName = void 0;
|