@evergis/react 4.0.137 → 4.0.139
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/LICENSE +21 -21
- package/README.md +7 -7
- package/dist/components/Dashboard/componentTypes.d.ts +10 -1
- package/dist/components/Dashboard/containers/VoteContainer/components/VoteCreateForm.d.ts +3 -0
- package/dist/components/Dashboard/containers/VoteContainer/components/VoteResults.d.ts +3 -0
- package/dist/components/Dashboard/containers/VoteContainer/components/VoteScreen.d.ts +9 -0
- package/dist/components/Dashboard/containers/VoteContainer/components/VoteShare.d.ts +3 -0
- package/dist/components/Dashboard/containers/VoteContainer/constants.d.ts +46 -0
- package/dist/components/Dashboard/containers/VoteContainer/hooks/useVoteActions.d.ts +26 -0
- package/dist/components/Dashboard/containers/VoteContainer/hooks/useVoteContainer.d.ts +25 -0
- package/dist/components/Dashboard/containers/VoteContainer/hooks/useVoteData.d.ts +22 -0
- package/dist/components/Dashboard/containers/VoteContainer/hooks/useVoteForm.d.ts +17 -0
- package/dist/components/Dashboard/containers/VoteContainer/hooks/useVoteUser.d.ts +14 -0
- package/dist/components/Dashboard/containers/VoteContainer/index.d.ts +11 -0
- package/dist/components/Dashboard/containers/VoteContainer/styled.d.ts +31 -0
- package/dist/components/Dashboard/containers/VoteContainer/types.d.ts +88 -0
- package/dist/components/Dashboard/containers/VoteContainer/utils.d.ts +38 -0
- package/dist/components/Dashboard/containers/index.d.ts +1 -0
- package/dist/components/Dashboard/containers/registry.d.ts +1 -0
- package/dist/components/Dashboard/types.d.ts +16 -2
- package/dist/hooks/map/index.d.ts +0 -1
- package/dist/index.js +4324 -3653
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +4327 -3656
- package/dist/react.esm.js.map +1 -1
- package/package.json +2 -3
- package/dist/hooks/map/useIconsFromLayers.d.ts +0 -52
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Everpoint
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Everpoint
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# @evergis/react
|
|
2
|
-
|
|
3
|
-
В данном репозитории находятся специфичные (в отличии от `@evergis/uilib-gl`) для `Evergis Online`,
|
|
4
|
-
но в целом переиспользуемые на других проектах, построенных на Evergis API, React-компоненты.
|
|
5
|
-
|
|
6
|
-
***ВАЖНО!!!***: Разрабатываемые компоненты не должны иметь зависимостей
|
|
7
|
-
от системы поддержки мультиязычности `Evergis Online`!
|
|
1
|
+
# @evergis/react
|
|
2
|
+
|
|
3
|
+
В данном репозитории находятся специфичные (в отличии от `@evergis/uilib-gl`) для `Evergis Online`,
|
|
4
|
+
но в целом переиспользуемые на других проектах, построенных на Evergis API, React-компоненты.
|
|
5
|
+
|
|
6
|
+
***ВАЖНО!!!***: Разрабатываемые компоненты не должны иметь зависимостей
|
|
7
|
+
от системы поддержки мультиязычности `Evergis Online`!
|
|
@@ -503,6 +503,14 @@ export interface UploadContainerConfig extends Omit<ConfigContainerChild, "optio
|
|
|
503
503
|
export interface UploadContainerProps extends Omit<ContainerProps, "elementConfig"> {
|
|
504
504
|
elementConfig?: UploadContainerConfig;
|
|
505
505
|
}
|
|
506
|
+
export type VoteContainerOptions = Pick<ConfigOptions, "categoryDataSource" | "questionDataSource" | "variantDataSource" | "answerDataSource" | "expandable" | "expanded"> & ContainerBoxOptions;
|
|
507
|
+
export interface VoteContainerConfig extends Omit<ConfigContainerChild, "options" | "templateName"> {
|
|
508
|
+
templateName?: ContainerTemplate.Vote;
|
|
509
|
+
options?: VoteContainerOptions;
|
|
510
|
+
}
|
|
511
|
+
export interface VoteContainerProps extends Omit<ContainerProps, "elementConfig"> {
|
|
512
|
+
elementConfig?: VoteContainerConfig;
|
|
513
|
+
}
|
|
506
514
|
export type DashboardDefaultHeaderOptions = Pick<ConfigOptions, "url">;
|
|
507
515
|
export interface DashboardDefaultHeaderConfig extends Omit<ConfigContainerHeader, "options" | "templateName"> {
|
|
508
516
|
templateName?: HeaderTemplate.Default;
|
|
@@ -532,7 +540,7 @@ export interface FeatureCardSlideshowHeaderConfig extends Omit<ConfigContainerHe
|
|
|
532
540
|
* Поскольку оба поля помечены как опциональные (`?`), значения **без** дискриминатора по-прежнему
|
|
533
541
|
* приемлемы для любой ветви — это переходная мягкая совместимость с legacy-конфигами.
|
|
534
542
|
*/
|
|
535
|
-
export type DashboardChild = ElementButtonConfig | ElementCameraConfig | ElementChartConfig | ElementChipsConfig | ElementControlConfig | ElementIconConfig | ElementImageConfig | ElementLegendConfig | ElementLinkConfig | ElementMarkdownConfig | ElementModalConfig | ElementSlideshowConfig | ElementSvgConfig | ElementTableConfig | ElementTooltipConfig | ElementUploaderConfig | AddFeatureContainerConfig | AttachmentContainerConfig | CameraContainerConfig | ChartContainerConfig | ContainersGroupContainerConfig | DataSourceContainerConfig | DataSourceProgressContainerConfig | DefaultAttributesContainerConfig | DividerContainerElementConfig | EditContainerConfig | EditGroupContainerConfig | EditBooleanContainerConfig | EditStringContainerConfig | EditNumberContainerConfig | EditDropdownContainerConfig | EditChipsContainerConfig | EditCheckboxContainerConfig | EditDateContainerConfig | EditAttachmentContainerConfig | ExportPdfContainerConfig | FiltersContainerConfig | GridRowContainerConfig | IconContainerConfig | ImageContainerConfig | LayersContainerConfig | OneColumnContainerConfig | ProgressContainerConfig | RoundedBackgroundContainerConfig | SlideshowContainerConfig | StructuredDataContainerConfig | TabsContainerConfig | TaskContainerConfig | TitleContainerConfig | TwoColumnContainerConfig | UploadContainerConfig;
|
|
543
|
+
export type DashboardChild = ElementButtonConfig | ElementCameraConfig | ElementChartConfig | ElementChipsConfig | ElementControlConfig | ElementIconConfig | ElementImageConfig | ElementLegendConfig | ElementLinkConfig | ElementMarkdownConfig | ElementModalConfig | ElementSlideshowConfig | ElementSvgConfig | ElementTableConfig | ElementTooltipConfig | ElementUploaderConfig | AddFeatureContainerConfig | AttachmentContainerConfig | CameraContainerConfig | ChartContainerConfig | ContainersGroupContainerConfig | DataSourceContainerConfig | DataSourceProgressContainerConfig | DefaultAttributesContainerConfig | DividerContainerElementConfig | EditContainerConfig | EditGroupContainerConfig | EditBooleanContainerConfig | EditStringContainerConfig | EditNumberContainerConfig | EditDropdownContainerConfig | EditChipsContainerConfig | EditCheckboxContainerConfig | EditDateContainerConfig | EditAttachmentContainerConfig | ExportPdfContainerConfig | FiltersContainerConfig | GridRowContainerConfig | IconContainerConfig | ImageContainerConfig | LayersContainerConfig | OneColumnContainerConfig | ProgressContainerConfig | RoundedBackgroundContainerConfig | SlideshowContainerConfig | StructuredDataContainerConfig | TabsContainerConfig | TaskContainerConfig | TitleContainerConfig | TwoColumnContainerConfig | UploadContainerConfig | VoteContainerConfig;
|
|
536
544
|
/**
|
|
537
545
|
* Строгий authoring-тип узла конфига. В отличие от мягкого {@link ConfigContainerChild}
|
|
538
546
|
* (`id?` — опционален ради legacy-совместимости), здесь `id` **обязателен** и рекурсивно
|
|
@@ -615,6 +623,7 @@ export type ContainerTemplateToProps = {
|
|
|
615
623
|
[ContainerTemplate.Title]: TitleContainerProps;
|
|
616
624
|
[ContainerTemplate.TwoColumn]: TwoColumnContainerProps;
|
|
617
625
|
[ContainerTemplate.Upload]: UploadContainerProps;
|
|
626
|
+
[ContainerTemplate.Vote]: VoteContainerProps;
|
|
618
627
|
};
|
|
619
628
|
/**
|
|
620
629
|
* Карта `type` → `<Name>ElementProps` для регистра элементов из `elements/registry.ts`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { VoteScreenProps } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Тело контейнера: выбирает экран по вью-модели голосования.
|
|
5
|
+
*
|
|
6
|
+
* Живёт отдельно от `VoteContainer`, потому что тот отвечает за корень контейнера — размеры,
|
|
7
|
+
* фон и заголовок — и не должен раздуваться ветвлением по состояниям.
|
|
8
|
+
*/
|
|
9
|
+
export declare const VoteScreen: FC<VoteScreenProps>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Имена полей таблиц голосования. */
|
|
2
|
+
export declare const VOTE_FIELDS: {
|
|
3
|
+
readonly category: {
|
|
4
|
+
readonly id: "id";
|
|
5
|
+
readonly name: "name";
|
|
6
|
+
};
|
|
7
|
+
readonly question: {
|
|
8
|
+
readonly id: "id";
|
|
9
|
+
readonly text: "text";
|
|
10
|
+
readonly categoryId: "category_id";
|
|
11
|
+
readonly userName: "user_name";
|
|
12
|
+
readonly multiSelect: "multi_select";
|
|
13
|
+
};
|
|
14
|
+
readonly variant: {
|
|
15
|
+
readonly id: "id";
|
|
16
|
+
readonly questionId: "question_id";
|
|
17
|
+
readonly text: "text";
|
|
18
|
+
};
|
|
19
|
+
readonly answer: {
|
|
20
|
+
readonly id: "id";
|
|
21
|
+
readonly questionId: "question_id";
|
|
22
|
+
readonly userName: "user_name";
|
|
23
|
+
readonly variantId: "variant_id";
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/** Минимальное число вариантов ответа в голосовании. */
|
|
27
|
+
export declare const MIN_VARIANTS = 2;
|
|
28
|
+
/** Лимит при чтении списков (вариантов/ответов/категорий). */
|
|
29
|
+
export declare const VOTE_FETCH_LIMIT = 10000;
|
|
30
|
+
/** База для перевода доли голосов в проценты. */
|
|
31
|
+
export declare const PERCENT_BASE = 100;
|
|
32
|
+
/** Namespace переводов потребляющего приложения (подписи берутся через `t` с defaultValue). */
|
|
33
|
+
export declare const VOTE_NS = "dashboard";
|
|
34
|
+
/**
|
|
35
|
+
* Имя публичного (анонимного) аккаунта портала.
|
|
36
|
+
*
|
|
37
|
+
* Под ним сервер отдаёт `getUserInfo()` любому неавторизованному посетителю шаренного проекта,
|
|
38
|
+
* поэтому «кто уже голосовал» по нему не считается: первый же голос закрыл бы голосование всем
|
|
39
|
+
* сразу. Такой посетитель для контейнера — неавторизованный, ему доступны только результаты.
|
|
40
|
+
*
|
|
41
|
+
* Признака анонима в API нет (`UserInfoDc` — это `username` + `roles`), поэтому имя приходится
|
|
42
|
+
* знать по конвенции портала: оно же стоит ролью в ACL публичных ресурсов.
|
|
43
|
+
*/
|
|
44
|
+
export declare const PUBLIC_USER_NAME = "public_user";
|
|
45
|
+
/** Социальные сети для блока «Поделиться». */
|
|
46
|
+
export declare const VOTE_SOCIALS: string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FeatureDc } from '@evergis/api';
|
|
2
|
+
import { VoteDataSources, VoteFormValues, VoteQuestion, VoteVariant } from '../types';
|
|
3
|
+
interface UseVoteActionsProps {
|
|
4
|
+
dataSources: VoteDataSources;
|
|
5
|
+
attributeName: string;
|
|
6
|
+
featureId?: string;
|
|
7
|
+
featureLayerName?: string;
|
|
8
|
+
username: string;
|
|
9
|
+
question: VoteQuestion | null;
|
|
10
|
+
variants: VoteVariant[];
|
|
11
|
+
answers: FeatureDc[];
|
|
12
|
+
onQuestionIdChange: (questionId: string) => void;
|
|
13
|
+
reload: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Операции записи контейнера: создание голосования, отправка ответа, редактирование и удаление.
|
|
17
|
+
* Все операции доступны только авторизованному пользователю.
|
|
18
|
+
*/
|
|
19
|
+
export declare const useVoteActions: ({ dataSources, attributeName, featureId, featureLayerName, username, question, variants, answers, onQuestionIdChange, reload, }: UseVoteActionsProps) => {
|
|
20
|
+
submitting: boolean;
|
|
21
|
+
createVote: (values: VoteFormValues) => Promise<void>;
|
|
22
|
+
submitAnswer: (variantIds: string[]) => Promise<void>;
|
|
23
|
+
editVote: (values: VoteFormValues) => Promise<void>;
|
|
24
|
+
deleteVote: () => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { VoteContainerConfig } from '../../../componentTypes';
|
|
2
|
+
import { VoteFormValues, VoteScreen } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Вью-модель контейнера голосования: определяет текущий экран и собирает данные/действия.
|
|
5
|
+
* Привязка к объекту карты — через `elementConfig.attributeName` (хранит `question_id`).
|
|
6
|
+
*/
|
|
7
|
+
export declare const useVoteContainer: (elementConfig?: VoteContainerConfig) => {
|
|
8
|
+
submitting: boolean;
|
|
9
|
+
createVote: (values: VoteFormValues) => Promise<void>;
|
|
10
|
+
submitAnswer: (variantIds: string[]) => Promise<void>;
|
|
11
|
+
editVote: (values: VoteFormValues) => Promise<void>;
|
|
12
|
+
deleteVote: () => Promise<void>;
|
|
13
|
+
configured: boolean;
|
|
14
|
+
screen: VoteScreen;
|
|
15
|
+
categories: import('../types').VoteCategory[];
|
|
16
|
+
question: import('../types').VoteQuestion;
|
|
17
|
+
category: import('../types').VoteCategory;
|
|
18
|
+
results: import('../types').VoteVariantResult[];
|
|
19
|
+
totalVotes: number;
|
|
20
|
+
isOwner: boolean;
|
|
21
|
+
hasAnswers: boolean;
|
|
22
|
+
isEditing: boolean;
|
|
23
|
+
setIsEditing: import('react').Dispatch<import('react').SetStateAction<boolean>>;
|
|
24
|
+
editInitialValues: VoteFormValues;
|
|
25
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FeatureDc } from '@evergis/api';
|
|
2
|
+
import { VoteCategory, VoteDataSources, VoteQuestion, VoteVariant } from '../types';
|
|
3
|
+
interface UseVoteDataProps {
|
|
4
|
+
dataSources: VoteDataSources;
|
|
5
|
+
questionId: string;
|
|
6
|
+
reloadToken: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Загружает справочник категорий, а по `questionId` — само голосование, его варианты и ответы.
|
|
10
|
+
* Перечитывается при смене `questionId` или `reloadToken` (после создания/голосования/правки).
|
|
11
|
+
*/
|
|
12
|
+
export declare const useVoteData: ({ dataSources, questionId, reloadToken }: UseVoteDataProps) => {
|
|
13
|
+
categories: VoteCategory[];
|
|
14
|
+
question: VoteQuestion;
|
|
15
|
+
variants: VoteVariant[];
|
|
16
|
+
answers: FeatureDc[];
|
|
17
|
+
results: import('../types').VoteVariantResult[];
|
|
18
|
+
totalVotes: number;
|
|
19
|
+
loading: boolean;
|
|
20
|
+
error: boolean;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { VoteFormValues, VoteFormVariant } from '../types';
|
|
2
|
+
/** Локальное состояние формы создания/редактирования голосования (категория, вопрос, чипсы-варианты). */
|
|
3
|
+
export declare const useVoteForm: (initialValues?: VoteFormValues) => {
|
|
4
|
+
categoryId: string;
|
|
5
|
+
setCategoryId: import('react').Dispatch<import('react').SetStateAction<string>>;
|
|
6
|
+
text: string;
|
|
7
|
+
setText: import('react').Dispatch<import('react').SetStateAction<string>>;
|
|
8
|
+
multiSelect: boolean;
|
|
9
|
+
setMultiSelect: import('react').Dispatch<import('react').SetStateAction<boolean>>;
|
|
10
|
+
variants: VoteFormVariant[];
|
|
11
|
+
addVariant: () => void;
|
|
12
|
+
removeVariant: (index: number) => void;
|
|
13
|
+
draft: string;
|
|
14
|
+
setDraft: import('react').Dispatch<import('react').SetStateAction<string>>;
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
values: VoteFormValues;
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Текущий пользователь для контейнера голосования. Авторизация обязательна — неавторизованный
|
|
3
|
+
* пользователь видит только результаты. Источник — `api.account.getUserInfo()`; ошибка/отсутствие
|
|
4
|
+
* `username` трактуются как «не авторизован».
|
|
5
|
+
*
|
|
6
|
+
* Публичный аккаунт портала (`PUBLIC_USER_NAME` в `username` или в ролях) авторизацией не
|
|
7
|
+
* считается: под ним ходят ВСЕ анонимные посетители шаренного проекта, поэтому и «мой голос»,
|
|
8
|
+
* и владение голосованием опознались бы у них общими на всех.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useVoteUser: () => {
|
|
11
|
+
username: string;
|
|
12
|
+
isAuthenticated: boolean;
|
|
13
|
+
loading: boolean;
|
|
14
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { VoteContainerProps } from '../../componentTypes';
|
|
3
|
+
/**
|
|
4
|
+
* Контейнер «Голосование»: привязывает опрос к объекту карты через `attributeName`
|
|
5
|
+
* и показывает один из экранов — создание, голосование, после голосования
|
|
6
|
+
* или (для неавторизованных) только результаты.
|
|
7
|
+
*
|
|
8
|
+
* Корнем владеет сам (`useContainerRoot`), поэтому шаблон записан в `ROOT_OWNING_TEMPLATES`:
|
|
9
|
+
* размеры, авторский `style`, фон и заголовок живут на одном узле, без внешней обёртки.
|
|
10
|
+
*/
|
|
11
|
+
export declare const VoteContainer: FC<VoteContainerProps>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RadioGroup } from '@evergis/uilib-gl';
|
|
2
|
+
export declare const VoteWrapper: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
3
|
+
export declare const VoteHeading: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
4
|
+
export declare const VoteQuestionText: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
5
|
+
export declare const VoteCategoryLabel: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
6
|
+
export declare const VoteSectionLabel: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
7
|
+
export declare const VoteChipList: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
8
|
+
export declare const VoteChip: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
9
|
+
/**
|
|
10
|
+
* Список вариантов ответа.
|
|
11
|
+
*
|
|
12
|
+
* Обёртка — именно `RadioGroup`: `Radio` из uilib читает его legacy-контекст и без него бросает
|
|
13
|
+
* `Radio must be controlled with RadioGroup context.` — даже когда `checked` и `onChange` заданы
|
|
14
|
+
* на самом контроле. Группа стоит всегда, а не только в режиме одиночного выбора: лишнего она не
|
|
15
|
+
* рисует, зато контекст не может пропасть при смене экрана.
|
|
16
|
+
*
|
|
17
|
+
* Подпись у `Radio` своя, но текст варианта рисует строка — он делит место со счётчиком и
|
|
18
|
+
* прогресс-баром. Поэтому пустой узел подписи и отступ кружка до него снимаются.
|
|
19
|
+
*/
|
|
20
|
+
export declare const VoteVariantList: import('styled-components').StyledComponent<typeof RadioGroup, any, {}, never>;
|
|
21
|
+
export declare const VoteVariantRow: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
22
|
+
export declare const VoteVariantHead: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
23
|
+
export declare const VoteVariantText: import('styled-components').StyledComponent<"span", any, {}, never>;
|
|
24
|
+
export declare const VoteVariantCount: import('styled-components').StyledComponent<"span", any, {}, never>;
|
|
25
|
+
export declare const VoteAcceptedBadge: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
26
|
+
export declare const VoteAuthHint: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
27
|
+
export declare const VoteEditLink: import('styled-components').StyledComponent<"button", any, {}, never>;
|
|
28
|
+
export declare const VoteShareBlock: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
29
|
+
export declare const VoteShareChips: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
|
|
30
|
+
export declare const VoteShareChip: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
31
|
+
export declare const VoteError: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { VoteContainerOptions } from '../../componentTypes';
|
|
2
|
+
/** Экран, который показывает контейнер голосования. */
|
|
3
|
+
export type VoteScreen = "loading" | "create" | "voting" | "voted" | "unauthenticated";
|
|
4
|
+
export interface VoteCategory {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
export interface VoteQuestion {
|
|
9
|
+
id: string;
|
|
10
|
+
text: string;
|
|
11
|
+
categoryId: string;
|
|
12
|
+
userName: string;
|
|
13
|
+
multiSelect: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface VoteVariant {
|
|
16
|
+
id: string;
|
|
17
|
+
text: string;
|
|
18
|
+
}
|
|
19
|
+
/** Вариант ответа с подсчитанными результатами. `percent` — доля от всех голосов (0..100). */
|
|
20
|
+
export interface VoteVariantResult extends VoteVariant {
|
|
21
|
+
count: number;
|
|
22
|
+
percent: number;
|
|
23
|
+
}
|
|
24
|
+
/** Полезная нагрузка формы создания/редактирования. */
|
|
25
|
+
export interface VoteFormValues {
|
|
26
|
+
categoryId: string;
|
|
27
|
+
text: string;
|
|
28
|
+
multiSelect: boolean;
|
|
29
|
+
variants: VoteFormVariant[];
|
|
30
|
+
}
|
|
31
|
+
/** Вариант в форме: для существующих — с `id` из БД, для новых — `id` пустой. */
|
|
32
|
+
export interface VoteFormVariant {
|
|
33
|
+
id?: string;
|
|
34
|
+
text: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Имена слоёв-таблиц голосования, гарантированно непустые.
|
|
38
|
+
*
|
|
39
|
+
* Берутся из `options` контейнера, но отдельно от остальных его опций: размеры и заголовок
|
|
40
|
+
* к данным отношения не имеют, а `Required<VoteContainerOptions>` потребовал бы и их.
|
|
41
|
+
*/
|
|
42
|
+
export type VoteDataSources = Required<Pick<VoteContainerOptions, "categoryDataSource" | "questionDataSource" | "variantDataSource" | "answerDataSource">>;
|
|
43
|
+
export interface VoteCreateFormProps {
|
|
44
|
+
categories: VoteCategory[];
|
|
45
|
+
initialValues?: VoteFormValues;
|
|
46
|
+
isEditing: boolean;
|
|
47
|
+
canDelete: boolean;
|
|
48
|
+
submitting: boolean;
|
|
49
|
+
onSubmit: (values: VoteFormValues) => void;
|
|
50
|
+
onDelete?: () => void;
|
|
51
|
+
onCancel?: () => void;
|
|
52
|
+
}
|
|
53
|
+
export interface VoteResultsProps {
|
|
54
|
+
question: VoteQuestion;
|
|
55
|
+
category?: VoteCategory;
|
|
56
|
+
results: VoteVariantResult[];
|
|
57
|
+
totalVotes: number;
|
|
58
|
+
screen: VoteScreen;
|
|
59
|
+
isOwner: boolean;
|
|
60
|
+
hasAnswers: boolean;
|
|
61
|
+
submitting: boolean;
|
|
62
|
+
onSubmit: (variantIds: string[]) => void;
|
|
63
|
+
onEdit?: () => void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Вью-модель голосования, которую контейнер отдаёт в тело (`VoteScreen`).
|
|
67
|
+
*
|
|
68
|
+
* Это ровно результат `useVoteContainer` без `configured`: признак настроенности разбирает сам
|
|
69
|
+
* контейнер — он решает, рисовать тело или ошибку блока, и до экранов этот флаг не доходит.
|
|
70
|
+
*/
|
|
71
|
+
export interface VoteScreenProps {
|
|
72
|
+
screen: VoteScreen;
|
|
73
|
+
categories: VoteCategory[];
|
|
74
|
+
question: VoteQuestion | null;
|
|
75
|
+
category?: VoteCategory;
|
|
76
|
+
results: VoteVariantResult[];
|
|
77
|
+
totalVotes: number;
|
|
78
|
+
isOwner: boolean;
|
|
79
|
+
hasAnswers: boolean;
|
|
80
|
+
isEditing: boolean;
|
|
81
|
+
setIsEditing: (isEditing: boolean) => void;
|
|
82
|
+
editInitialValues?: VoteFormValues;
|
|
83
|
+
submitting: boolean;
|
|
84
|
+
createVote: (values: VoteFormValues) => Promise<void>;
|
|
85
|
+
submitAnswer: (variantIds: string[]) => Promise<void>;
|
|
86
|
+
editVote: (values: VoteFormValues) => Promise<void>;
|
|
87
|
+
deleteVote: () => Promise<void>;
|
|
88
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FeatureDc } from '@evergis/api';
|
|
2
|
+
import { VoteCategory, VoteFormVariant, VoteQuestion, VoteVariant, VoteVariantResult } from './types';
|
|
3
|
+
/** Приводит значение атрибута к строке-идентификатору (id приходят числами/строками). */
|
|
4
|
+
export declare const toId: (value: unknown) => string;
|
|
5
|
+
/**
|
|
6
|
+
* Условие равенства по числовому полю для `conditions` слоя: `field == value`.
|
|
7
|
+
*
|
|
8
|
+
* Двойное равенство — форма, которой написаны условия во всех конфигах проекта; лексер языка
|
|
9
|
+
* условий принимает и одиночное `=`, но расходиться с авторскими конфигами незачем.
|
|
10
|
+
*/
|
|
11
|
+
export declare const eqCondition: (field: string, value: string | number) => string;
|
|
12
|
+
export declare const mapCategories: (features: FeatureDc[]) => VoteCategory[];
|
|
13
|
+
export declare const mapQuestion: (feature: FeatureDc) => VoteQuestion;
|
|
14
|
+
export declare const mapVariants: (features: FeatureDc[]) => VoteVariant[];
|
|
15
|
+
/** Список `variant_id` из ответов конкретного пользователя. */
|
|
16
|
+
export declare const getUserVariantIds: (answers: FeatureDc[], userName: string) => string[];
|
|
17
|
+
/** Id записей-ответов конкретного пользователя (для замены ответа при переголосовании). */
|
|
18
|
+
export declare const getUserAnswerIds: (answers: FeatureDc[], userName: string) => string[];
|
|
19
|
+
/**
|
|
20
|
+
* Считает голоса по вариантам. `percent` — доля голосов варианта от общего числа голосов
|
|
21
|
+
* по голосованию.
|
|
22
|
+
*/
|
|
23
|
+
export declare const computeResults: (variants: VoteVariant[], answers: FeatureDc[]) => {
|
|
24
|
+
results: VoteVariantResult[];
|
|
25
|
+
totalVotes: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Сравнивает варианты из формы с существующими в БД и раскладывает на наборы операций:
|
|
29
|
+
* создать (новые без id), обновить (изменился текст) и удалить (исчезли из формы).
|
|
30
|
+
*/
|
|
31
|
+
export declare const diffVariants: (existing: VoteVariant[], next: VoteFormVariant[]) => {
|
|
32
|
+
toCreate: string[];
|
|
33
|
+
toUpdate: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}>;
|
|
37
|
+
toDeleteIds: string[];
|
|
38
|
+
};
|
|
@@ -57,6 +57,7 @@ export declare const getContainerComponents: () => {
|
|
|
57
57
|
readonly EditAttachment: FC<import('../componentTypes').EditAttachmentContainerProps>;
|
|
58
58
|
readonly Attachment: FC<import('../componentTypes').AttachmentContainerProps>;
|
|
59
59
|
readonly EditGroup: FC<import('../componentTypes').EditGroupContainerProps>;
|
|
60
|
+
readonly Vote: FC<import('../componentTypes').VoteContainerProps>;
|
|
60
61
|
readonly ContainersGroup: FC<import('../componentTypes').ContainersGroupContainerProps>;
|
|
61
62
|
readonly GridRow: FC<import('../componentTypes').GridRowContainerProps>;
|
|
62
63
|
readonly StructuredData: FC<import('../componentTypes').StructuredDataContainerProps>;
|
|
@@ -440,6 +440,19 @@ export interface ConfigEntityRefOptions {
|
|
|
440
440
|
parentResourceId?: string;
|
|
441
441
|
downloadById?: string;
|
|
442
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* Опции контейнера «Голосование» (`ContainerTemplate.Vote`).
|
|
445
|
+
*
|
|
446
|
+
* Каждое поле — имя DataSource-таблицы проекта, к которой обращается runtime контейнера:
|
|
447
|
+
* категории, голосования, варианты ответов и ответы пользователей. `question_id` созданного
|
|
448
|
+
* голосования пишется в атрибут объекта карты (см. {@link ConfigContainerChild.attributeName}).
|
|
449
|
+
*/
|
|
450
|
+
export interface ConfigVoteOptions {
|
|
451
|
+
categoryDataSource?: string;
|
|
452
|
+
questionDataSource?: string;
|
|
453
|
+
variantDataSource?: string;
|
|
454
|
+
answerDataSource?: string;
|
|
455
|
+
}
|
|
443
456
|
/** Прочее — поля без явного домена, обычно широкого назначения. */
|
|
444
457
|
export interface ConfigMiscOptions {
|
|
445
458
|
innerTemplateName?: ContainerTemplate;
|
|
@@ -463,7 +476,7 @@ export interface ConfigMiscOptions {
|
|
|
463
476
|
* `Pick<ConfigOptions, ...>`, продолжают работать. Для нового кода предпочтительно делать
|
|
464
477
|
* `Pick<Config<Domain>Options, ...>` — это лучше документирует, к какому домену относится опция.
|
|
465
478
|
*/
|
|
466
|
-
export interface ConfigOptions extends ConfigLayoutOptions, ConfigTypographyOptions, ConfigExpandableOptions, ConfigDataSourceBindingOptions, ConfigChartOptions, ConfigVisualOptions, ConfigTextDisplayOptions, ConfigCollectionOptions, ConfigMapLayerOptions, ConfigEditOptions, ConfigMiscOptions {
|
|
479
|
+
export interface ConfigOptions extends ConfigLayoutOptions, ConfigTypographyOptions, ConfigExpandableOptions, ConfigDataSourceBindingOptions, ConfigChartOptions, ConfigVisualOptions, ConfigTextDisplayOptions, ConfigCollectionOptions, ConfigMapLayerOptions, ConfigEditOptions, ConfigVoteOptions, ConfigMiscOptions {
|
|
467
480
|
}
|
|
468
481
|
/**
|
|
469
482
|
* Настройки атрибута источника данных, заданные в конфиге.
|
|
@@ -733,7 +746,8 @@ export declare enum ContainerTemplate {
|
|
|
733
746
|
EditAttachment = "EditAttachment",
|
|
734
747
|
Attachment = "Attachment",
|
|
735
748
|
Divider = "Divider",
|
|
736
|
-
StructuredData = "StructuredData"
|
|
749
|
+
StructuredData = "StructuredData",
|
|
750
|
+
Vote = "Vote"
|
|
737
751
|
}
|
|
738
752
|
export declare enum HeaderTemplate {
|
|
739
753
|
Default = "Default",
|