@irontec/ivoz-ui 1.7.12 → 1.7.13

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 (28) hide show
  1. package/components/Dashboard/Dashboard.js +5 -5
  2. package/components/shared/ConfirmDialog.styles.d.ts +2 -2
  3. package/entities/EntityInterface.d.ts +5 -0
  4. package/helpers/fetchFilteredPage.d.ts +9 -0
  5. package/helpers/fetchFilteredPage.js +31 -0
  6. package/helpers/index.d.ts +2 -0
  7. package/helpers/index.js +2 -0
  8. package/index.d.ts +1 -0
  9. package/index.js +1 -0
  10. package/package.json +1 -1
  11. package/services/form/Field/DynamicAutocomplete/DynamicAutocomplete.d.ts +25 -0
  12. package/services/form/Field/DynamicAutocomplete/DynamicAutocomplete.js +194 -0
  13. package/services/form/Field/DynamicAutocomplete/DynamicAutocomplete.styles.d.ts +1 -0
  14. package/services/form/Field/DynamicAutocomplete/DynamicAutocomplete.styles.js +6 -0
  15. package/services/form/Field/DynamicAutocomplete/index.d.ts +2 -0
  16. package/services/form/Field/DynamicAutocomplete/index.js +2 -0
  17. package/services/form/Field/index.d.ts +1 -0
  18. package/services/form/Field/index.js +1 -0
  19. package/services/form/FormFieldFactory/Factory/DynamicAutocompleteFactory.d.ts +22 -0
  20. package/services/form/FormFieldFactory/Factory/DynamicAutocompleteFactory.js +6 -0
  21. package/services/form/FormFieldFactory/Factory/index.d.ts +2 -1
  22. package/services/form/FormFieldFactory/Factory/index.js +2 -1
  23. package/services/form/FormFieldFactory/FormFieldFactory.d.ts +1 -0
  24. package/services/form/FormFieldFactory/FormFieldFactory.js +18 -1
  25. package/translations/ca.json +2 -0
  26. package/translations/en.json +3 -1
  27. package/translations/es.json +3 -1
  28. package/translations/it.json +2 -0
@@ -10,12 +10,12 @@ const Dashboard = (props) => {
10
10
  return { name, platform, dLicences, mLicenses };
11
11
  }
12
12
  const rows = [
13
- createData('Acies Abogados', 'IvozProvider Irontec', 10, 8),
14
- createData('Ayuntamiento Bilbao', 'IvozProvider Irontec', 10, 8),
15
- createData('BicBerrilan', 'IvozProvider Irontec', 10, 8),
16
- createData('CaritasSoria', 'IvozProvider Irontec', 10, 8),
13
+ createData('Client 1', 'Platform A', 5, 3),
14
+ createData('Client 2', 'Platform B', 8, 2),
15
+ createData('Client 3', 'Platform C', 4, 6),
16
+ createData('Client 4', 'Platform D', 7, 1),
17
17
  ];
18
- return (_jsxs("section", Object.assign({ className: className }, { children: [_jsx("div", Object.assign({ className: 'card welcome' }, { children: _jsxs("div", Object.assign({ className: 'card-container' }, { children: [_jsxs("div", { children: [_jsxs("h3", { children: ["Welcome to ", _jsx("br", {}), " Advanced Provisioning System"] }), _jsx("p", { children: "APS is an Open Source solution by Irontec. Add platforms, manage clients, assign license to VoIP users and much more." }), _jsx(LightButton, { children: "Get started" })] }), _jsx("img", { src: 'assets/img/dashboard-welcome.svg' })] })) })), _jsxs("div", Object.assign({ className: 'card activity' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Recent activity" })), _jsxs("div", Object.assign({ className: 'content' }, { children: [_jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "5m" })), _jsx("div", Object.assign({ className: 'value' }, { children: "Login (Antonio)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "30m" })), _jsx("div", Object.assign({ className: 'value' }, { children: "New admin added (Mikel)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "6h" })), _jsx("div", Object.assign({ className: 'value' }, { children: "Login (Mikel)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "1d" })), _jsx("div", Object.assign({ className: 'value' }, { children: "10 new licenses assigned (Carlos)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "1d" })), _jsx("div", Object.assign({ className: 'value' }, { children: "New client added (Carlos)" }))] }))] }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconPlatformsDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "5" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Platforms" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "+ 0" }), _jsx("img", { src: 'assets/img/same.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "Go to platforms" }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconClientsDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "120" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Clients" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "+ 3" }), _jsx("img", { src: 'assets/img/up.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "Go to clients" }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconUsersDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "1264" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Users" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "- 15" }), _jsx("img", { src: 'assets/img/down.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "Go to users" }))] })), _jsxs("div", Object.assign({ className: 'card licenses' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Licenses" })), _jsxs("div", Object.assign({ className: 'radial' }, { children: [_jsx("div", { className: 'circle' }), _jsxs("div", Object.assign({ className: 'data' }, { children: [_jsx("div", Object.assign({ className: 'total' }, { children: "Total" })), _jsx("div", Object.assign({ className: 'number' }, { children: "1632" }))] }))] })), _jsxs("div", Object.assign({ className: 'legend' }, { children: [_jsxs("div", Object.assign({ className: 'label' }, { children: [_jsx("div", { className: 'color orange' }), _jsx("div", Object.assign({ className: 'text' }, { children: "Desktop" }))] })), _jsxs("div", Object.assign({ className: 'label' }, { children: [_jsx("div", { className: 'color red' }), _jsx("div", Object.assign({ className: 'text' }, { children: "Mobile" }))] }))] }))] })), _jsxs("div", Object.assign({ className: 'card last' }, { children: [_jsxs("div", Object.assign({ className: 'header' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Last added clients" })), _jsx(SolidButton, { children: "+ Add" })] })), _jsx("div", Object.assign({ className: 'table' }, { children: _jsx(TableContainer, Object.assign({ component: Paper, sx: { boxShadow: 'none' } }, { children: _jsxs(Table, Object.assign({ sx: { minWidth: 650 }, "aria-label": 'simple table' }, { children: [_jsx(TableHead, { children: _jsxs(TableRow, Object.assign({ style: { fontSize: '13px' } }, { children: [_jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Name" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Platform" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Desktop licenses" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Mobile licenses" }))] })) }), _jsx(TableBody, { children: rows.map((row) => (_jsxs(TableRow, Object.assign({ sx: { '&:last-child td, &:last-child th': { border: 0 } } }, { children: [_jsx(TableCell, Object.assign({ component: 'th', scope: 'row' }, { children: row.name })), _jsx(TableCell, { children: row.platform }), _jsx(TableCell, { children: row.dLicences }), _jsx(TableCell, { children: row.mLicenses })] }), row.name))) })] })) })) }))] }))] })));
18
+ return (_jsxs("section", Object.assign({ className: className }, { children: [_jsx("div", Object.assign({ className: 'card welcome' }, { children: _jsxs("div", Object.assign({ className: 'card-container' }, { children: [_jsxs("div", { children: [_jsxs("h3", { children: ["Welcome to ", _jsx("br", {}), " Demo System"] }), _jsx("p", { children: "This is a demo. Add platforms, manage clients, assign licenses and more." }), _jsx(LightButton, { children: "Get started" })] }), _jsx("img", { src: 'assets/img/dashboard-welcome.svg' })] })) })), _jsxs("div", Object.assign({ className: 'card activity' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Recent activity" })), _jsxs("div", Object.assign({ className: 'content' }, { children: [_jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "5m" })), _jsx("div", Object.assign({ className: 'value' }, { children: "Login (User1)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "30m" })), _jsx("div", Object.assign({ className: 'value' }, { children: "New admin added (User2)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "6h" })), _jsx("div", Object.assign({ className: 'value' }, { children: "Login (User2)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "1d" })), _jsx("div", Object.assign({ className: 'value' }, { children: "10 licenses assigned (User3)" }))] })), _jsxs("div", Object.assign({ className: 'row' }, { children: [_jsx("div", Object.assign({ className: 'time' }, { children: "1d" })), _jsx("div", Object.assign({ className: 'value' }, { children: "New client added (User3)" }))] }))] }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconPlatformsDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "4" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Platforms" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "+ 0" }), _jsx("img", { src: 'assets/img/same.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "View platforms" }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconClientsDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "20" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Clients" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "+ 1" }), _jsx("img", { src: 'assets/img/up.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "View clients" }))] })), _jsxs("div", Object.assign({ className: 'card amount' }, { children: [_jsx("div", Object.assign({ className: 'img-container' }, { children: _jsx(IconUsersDashboard, {}) })), _jsx("div", Object.assign({ className: 'number' }, { children: "100" })), _jsx("div", Object.assign({ className: 'name' }, { children: "Users" })), _jsxs("div", Object.assign({ className: 'progress' }, { children: [_jsx("span", { children: "- 2" }), _jsx("img", { src: 'assets/img/down.svg' })] })), _jsx("a", Object.assign({ href: '', className: 'link' }, { children: "View users" }))] })), _jsxs("div", Object.assign({ className: 'card licenses' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Licenses" })), _jsxs("div", Object.assign({ className: 'radial' }, { children: [_jsx("div", { className: 'circle' }), _jsxs("div", Object.assign({ className: 'data' }, { children: [_jsx("div", Object.assign({ className: 'total' }, { children: "Total" })), _jsx("div", Object.assign({ className: 'number' }, { children: "120" }))] }))] })), _jsxs("div", Object.assign({ className: 'legend' }, { children: [_jsxs("div", Object.assign({ className: 'label' }, { children: [_jsx("div", { className: 'color orange' }), _jsx("div", Object.assign({ className: 'text' }, { children: "Desktop" }))] })), _jsxs("div", Object.assign({ className: 'label' }, { children: [_jsx("div", { className: 'color red' }), _jsx("div", Object.assign({ className: 'text' }, { children: "Mobile" }))] }))] }))] })), _jsxs("div", Object.assign({ className: 'card last' }, { children: [_jsxs("div", Object.assign({ className: 'header' }, { children: [_jsx("div", Object.assign({ className: 'title' }, { children: "Last added clients" })), _jsx(SolidButton, { children: "+ Add" })] })), _jsx("div", Object.assign({ className: 'table' }, { children: _jsx(TableContainer, Object.assign({ component: Paper, sx: { boxShadow: 'none' } }, { children: _jsxs(Table, Object.assign({ sx: { minWidth: 650 }, "aria-label": 'simple table' }, { children: [_jsx(TableHead, { children: _jsxs(TableRow, Object.assign({ style: { fontSize: '13px' } }, { children: [_jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Name" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Platform" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Desktop licenses" })), _jsx(TableCell, Object.assign({ style: { fontSize: '13px', color: 'var(--color-text)' } }, { children: "Mobile licenses" }))] })) }), _jsx(TableBody, { children: rows.map((row) => (_jsxs(TableRow, Object.assign({ sx: { '&:last-child td, &:last-child th': { border: 0 } } }, { children: [_jsx(TableCell, Object.assign({ component: 'th', scope: 'row' }, { children: row.name })), _jsx(TableCell, { children: row.platform }), _jsx(TableCell, { children: row.dLicences }), _jsx(TableCell, { children: row.mLicenses })] }), row.name))) })] })) })) }))] }))] })));
19
19
  };
20
20
  export default styled(Dashboard)(({ theme }) => {
21
21
  return {
@@ -10,8 +10,8 @@ export declare const StyledDialogContentText: import("@emotion/styled").StyledCo
10
10
  noWrap?: boolean | undefined;
11
11
  paragraph?: boolean | undefined;
12
12
  sx?: import("@mui/material").SxProps<import("@mui/material").Theme> | undefined;
13
- variant?: "button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "subtitle1" | "subtitle2" | "body1" | "body2" | "overline" | undefined;
14
- variantMapping?: Partial<Record<"button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "subtitle1" | "subtitle2" | "body1" | "body2" | "overline", string>> | undefined;
13
+ variant?: "button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "overline" | "subtitle1" | "subtitle2" | "body1" | "body2" | undefined;
14
+ variantMapping?: Partial<Record<"button" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "inherit" | "overline" | "subtitle1" | "subtitle2" | "body1" | "body2", string>> | undefined;
15
15
  }, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "key" | keyof import("react").HTMLAttributes<HTMLSpanElement>> & {
16
16
  ref?: ((instance: HTMLSpanElement | null) => void) | import("react").RefObject<HTMLSpanElement> | null | undefined;
17
17
  }, "children" | keyof import("@mui/material/OverridableComponent").CommonProps | "sx" | "variant" | "align" | ("color" | "p" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxShadow" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "fontWeight" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "zIndex" | "border" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "noWrap" | "gutterBottom" | "paragraph" | "variantMapping"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
@@ -47,6 +47,10 @@ export declare type SelectOptionsArgs = {
47
47
  callback: FetchFksCallback;
48
48
  cancelToken?: CancelToken;
49
49
  };
50
+ export declare type DynamicSelectOptionsArgs = {
51
+ searchTerm?: string;
52
+ id?: string;
53
+ };
50
54
  export declare type SelectOptionsType<T = any> = (props: SelectOptionsArgs, customProps?: T) => Promise<unknown>;
51
55
  export declare type EntityAclType = {
52
56
  iden?: string;
@@ -90,6 +94,7 @@ export default interface EntityInterface {
90
94
  foreignKeyResolver: () => Promise<foreignKeyResolverType>;
91
95
  foreignKeyGetter: () => Promise<ForeignKeyGetterType>;
92
96
  selectOptions?: () => Promise<SelectOptionsType>;
97
+ dynamicSelectOptions?: boolean;
93
98
  Form: () => Promise<React.FunctionComponent<EntityFormProps>>;
94
99
  View: () => Promise<ViewType>;
95
100
  List: React.FunctionComponent<ListContentProps>;
@@ -0,0 +1,9 @@
1
+ import { CancelToken } from 'axios';
2
+ import { FetchFksCallback } from '../entities/EntityInterface';
3
+ export declare type fetchFilteredPageProps = {
4
+ endpoint: string;
5
+ params: Record<string, unknown>;
6
+ setter: FetchFksCallback;
7
+ cancelToken?: CancelToken;
8
+ };
9
+ export declare const fetchFilteredPage: (props: fetchFilteredPageProps) => Promise<unknown>;
@@ -0,0 +1,31 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { StoreContainer } from '../store';
11
+ export const fetchFilteredPage = (props) => __awaiter(void 0, void 0, void 0, function* () {
12
+ const { endpoint, params, setter, cancelToken } = props;
13
+ const getAction = StoreContainer.store.getActions().api.get;
14
+ const response = [];
15
+ try {
16
+ yield getAction({
17
+ path: endpoint,
18
+ silenceErrors: false,
19
+ params: Object.assign(Object.assign({ _itemsPerPage: 20 }, params), { _pagination: true, _page: 1 }),
20
+ successCallback: (data) => __awaiter(void 0, void 0, void 0, function* () {
21
+ response.push(...data);
22
+ }),
23
+ cancelToken,
24
+ });
25
+ }
26
+ catch (error) {
27
+ console.error(error);
28
+ }
29
+ setter(response);
30
+ return response;
31
+ });
@@ -0,0 +1,2 @@
1
+ export * from './fechAllPages';
2
+ export * from './fetchFilteredPage';
@@ -0,0 +1,2 @@
1
+ export * from './fechAllPages';
2
+ export * from './fetchFilteredPage';
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './components';
2
2
  export * from './entities';
3
+ export * from './helpers';
3
4
  export * from './hooks';
4
5
  export * from './router';
5
6
  export * from './services';
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './components';
2
2
  export * from './entities';
3
+ export * from './helpers';
3
4
  export * from './hooks';
4
5
  export * from './router';
5
6
  export * from './services';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@irontec/ivoz-ui",
3
- "version": "1.7.12",
3
+ "version": "1.7.13",
4
4
  "description": "UI library used in ivozprovider",
5
5
  "license": "GPL-3.0",
6
6
  "main": "index.js",
@@ -0,0 +1,25 @@
1
+ import { InputProps } from '@mui/material';
2
+ import React, { JSXElementConstructor, ReactElement } from 'react';
3
+ import { SelectOptionsType } from 'entities/EntityInterface';
4
+ import { FormOnChangeEvent } from 'entities/DefaultEntityBehavior/Form/Form';
5
+ export interface DynamicAutocompleteProps {
6
+ selectOptions: (() => Promise<SelectOptionsType>) | undefined;
7
+ nullOption?: string | React.ReactElement<any>;
8
+ className?: string;
9
+ name: string;
10
+ label: string | ReactElement<any, string | JSXElementConstructor<any>>;
11
+ placeholder?: string;
12
+ value: any;
13
+ multiple: boolean;
14
+ required: boolean;
15
+ disabled: boolean;
16
+ onBlur: (event: React.FocusEvent) => void;
17
+ error?: boolean;
18
+ errorMsg?: React.ReactNode;
19
+ helperText?: string | React.ReactNode;
20
+ hasChanged: boolean;
21
+ InputProps?: Partial<InputProps>;
22
+ onChange: (event: FormOnChangeEvent) => void;
23
+ }
24
+ declare const DynamicAutocomplete: (props: DynamicAutocompleteProps) => JSX.Element | null;
25
+ export default DynamicAutocomplete;
@@ -0,0 +1,194 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Paper, Typography } from '@mui/material';
3
+ import MuiAutocomplete from '@mui/material/Autocomplete';
4
+ import { useCallback, useEffect, useState, useRef, } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { StyledAutocompleteTextField } from '../TextField';
7
+ import SearchIcon from '@mui/icons-material/Search';
8
+ const DynamicAutocomplete = (props) => {
9
+ var _a;
10
+ const { nullOption, name, label, required, multiple, disabled, onBlur, error, errorMsg, helperText, hasChanged, value, selectOptions, onChange, } = props;
11
+ const { t } = useTranslation();
12
+ let className = props.className;
13
+ if (hasChanged) {
14
+ className += ' changed';
15
+ }
16
+ if (multiple) {
17
+ className += ' multiselect';
18
+ }
19
+ const nullOptionObject = nullOption
20
+ ? { id: '__null__', label: nullOption }
21
+ : null;
22
+ const [arrayChoices, setArrayChoices] = useState(nullOptionObject ? [nullOptionObject] : []);
23
+ const [searchTerm, setSearchTerm] = useState('');
24
+ const [loading, setLoading] = useState(false);
25
+ const [open, setOpen] = useState(false);
26
+ const [currentOption, setCurrentOption] = useState(nullOptionObject);
27
+ const debounceTimeoutRef = useRef();
28
+ const setOptions = useCallback((options) => {
29
+ const isCurrentOptionIncluded = options.some((option) => option.id == (currentOption === null || currentOption === void 0 ? void 0 : currentOption.id));
30
+ if (!isCurrentOptionIncluded &&
31
+ currentOption &&
32
+ currentOption.id !== '__null__') {
33
+ options.unshift(currentOption);
34
+ }
35
+ if (nullOptionObject) {
36
+ options.unshift(nullOptionObject);
37
+ }
38
+ console.log('setOptions', options);
39
+ setArrayChoices(options);
40
+ }, [nullOptionObject, currentOption]);
41
+ useEffect(() => {
42
+ const hasOptions = arrayChoices.some((option) => option.id !== '__null__');
43
+ if (hasOptions) {
44
+ return;
45
+ }
46
+ const searchParams = {};
47
+ if (value) {
48
+ searchParams.id = value;
49
+ }
50
+ selectOptions === null || selectOptions === void 0 ? void 0 : selectOptions().then((selectOptions) => {
51
+ selectOptions({
52
+ callback: (options) => {
53
+ if (options.length > 0) {
54
+ setOptions(options);
55
+ }
56
+ },
57
+ }, searchParams);
58
+ });
59
+ }, []);
60
+ useEffect(() => {
61
+ if (!selectOptions) {
62
+ return;
63
+ }
64
+ if (debounceTimeoutRef.current) {
65
+ clearTimeout(debounceTimeoutRef.current);
66
+ }
67
+ const searchTermMatchNullOption = getOptionLabel(nullOptionObject) === searchTerm;
68
+ if (searchTermMatchNullOption) {
69
+ return;
70
+ }
71
+ const isSearchTermIncluded = arrayChoices === null || arrayChoices === void 0 ? void 0 : arrayChoices.some((option) => getOptionLabel(option).includes(searchTerm));
72
+ if (isSearchTermIncluded) {
73
+ return;
74
+ }
75
+ setLoading(true);
76
+ debounceTimeoutRef.current = setTimeout(() => {
77
+ selectOptions().then((selectOptions) => {
78
+ selectOptions({
79
+ callback: (options) => {
80
+ setLoading(false);
81
+ setOptions(options);
82
+ },
83
+ }, {
84
+ searchTerm: searchTerm,
85
+ });
86
+ });
87
+ }, 500);
88
+ }, [searchTerm, selectOptions]);
89
+ const handleInputChange = useCallback((e, value, reason) => {
90
+ console.log('inputChange', arrayChoices);
91
+ if (reason === 'clear') {
92
+ setSearchTerm('');
93
+ return;
94
+ }
95
+ if (reason === 'input') {
96
+ setSearchTerm(value);
97
+ return;
98
+ }
99
+ if (reason === 'reset') {
100
+ if (arrayChoices.length === 0) {
101
+ setSearchTerm('');
102
+ }
103
+ }
104
+ }, []);
105
+ const onChangeWrapper = useCallback((e, option, reason) => {
106
+ let selectedValue = undefined;
107
+ if (reason !== 'clear' && option !== null) {
108
+ selectedValue = multiple
109
+ ? option.map((item) => typeof item === 'object' ? item.id : item)
110
+ : option.id;
111
+ }
112
+ else if (reason === 'clear') {
113
+ selectedValue = '';
114
+ }
115
+ else {
116
+ selectedValue = (arrayChoices === null || arrayChoices === void 0 ? void 0 : arrayChoices.find((item) => item.id === '__null__'))
117
+ ? '__null__'
118
+ : null;
119
+ }
120
+ setCurrentOption(option);
121
+ onChange({
122
+ target: {
123
+ name: name,
124
+ value: selectedValue,
125
+ },
126
+ });
127
+ }, [multiple, onChange, name, arrayChoices]);
128
+ const getOptionLabel = useCallback((value) => {
129
+ var _a, _b, _c, _d, _e, _f;
130
+ if (typeof value !== 'object') {
131
+ value = arrayChoices === null || arrayChoices === void 0 ? void 0 : arrayChoices.find((option) => option.id == value);
132
+ }
133
+ const isTranslation = (value === null || value === void 0 ? void 0 : value.label) &&
134
+ typeof value.label === 'object' &&
135
+ ((_b = (_a = value.label) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.defaults) &&
136
+ typeof ((_d = (_c = value.label) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.defaults) === 'string';
137
+ if (isTranslation) {
138
+ const translatableText = (_f = (_e = value.label) === null || _e === void 0 ? void 0 : _e.props) === null || _f === void 0 ? void 0 : _f.defaults;
139
+ return t(translatableText);
140
+ }
141
+ return (value === null || value === void 0 ? void 0 : value.label) || '';
142
+ }, [arrayChoices, t]);
143
+ const isOptionEqualToValue = useCallback((option, value) => {
144
+ if (value === (currentOption === null || currentOption === void 0 ? void 0 : currentOption.id)) {
145
+ return true;
146
+ }
147
+ if ((option === null || option === void 0 ? void 0 : option.id) == value) {
148
+ return true;
149
+ }
150
+ if ((option === null || option === void 0 ? void 0 : option.id) == value.id) {
151
+ return true;
152
+ }
153
+ return false;
154
+ }, []);
155
+ const arrayChoicesLength = (_a = arrayChoices === null || arrayChoices === void 0 ? void 0 : arrayChoices.length) !== null && _a !== void 0 ? _a : 0;
156
+ const renderInput = useCallback((props) => {
157
+ const inputProps = Object.assign(Object.assign({}, props.InputProps), { notched: true });
158
+ const showPlaceholder = !searchTerm && !loading;
159
+ const inputPlaceholder = showPlaceholder
160
+ ? t('Type to search')
161
+ : props.placeholder;
162
+ return (_jsx(StyledAutocompleteTextField, Object.assign({}, props, { name: name, label: label, required: required, disabled: disabled, InputProps: inputProps, InputLabelProps: { shrink: true, required: required }, error: error, errorMsg: errorMsg, helperText: helperText, placeholder: inputPlaceholder })));
163
+ }, [
164
+ name,
165
+ label,
166
+ required,
167
+ disabled,
168
+ error,
169
+ errorMsg,
170
+ helperText,
171
+ arrayChoicesLength,
172
+ searchTerm,
173
+ loading,
174
+ ]);
175
+ const dropdownHelperText = 'Type to load more options';
176
+ const CustomOption = useCallback((props) => {
177
+ return (_jsxs(Paper, Object.assign({}, props, { children: [props.children, dropdownHelperText && (_jsxs(Box, Object.assign({ sx: {
178
+ p: 2,
179
+ borderTop: '1px solid',
180
+ borderColor: 'divider',
181
+ backgroundColor: 'var(--color-background)',
182
+ color: 'var(--color-text)',
183
+ display: 'flex',
184
+ alignItems: 'center',
185
+ gap: '4px',
186
+ } }, { children: [_jsx(SearchIcon, { sx: { fontSize: '18px' } }), _jsx(Typography, Object.assign({ variant: 'caption' }, { children: t(dropdownHelperText) }))] })))] })));
187
+ }, [dropdownHelperText]);
188
+ const disableClearable = arrayChoices.find((item) => item.id === '__null__')
189
+ ? false
190
+ : true;
191
+ const safeValue = value.length !== '' ? value : null;
192
+ return (_jsx(MuiAutocomplete, { className: 'dynamic-autocomplete' + className, value: safeValue, multiple: multiple, disabled: disabled, disableClearable: disableClearable, onChange: onChangeWrapper, onBlur: onBlur, onInputChange: handleInputChange, onClose: () => setOpen(false), onOpen: () => setOpen(true), options: arrayChoices !== null && arrayChoices !== void 0 ? arrayChoices : [], getOptionLabel: getOptionLabel, isOptionEqualToValue: isOptionEqualToValue, loading: loading, placeholder: props.placeholder, renderInput: renderInput, PaperComponent: CustomOption, renderOption: (props, option) => (_jsx(Box, Object.assign({ component: 'li', className: 'autocomplete-option', "data-value": option.id }, props, { children: option.label }))) }));
193
+ };
194
+ export default DynamicAutocomplete;
@@ -0,0 +1 @@
1
+ export declare const StyledDynamicAutocomplete: import("@emotion/styled").StyledComponent<import("./DynamicAutocomplete").DynamicAutocompleteProps & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
@@ -0,0 +1,6 @@
1
+ import { styled } from '@mui/material';
2
+ import DynamicAutocomplete from './DynamicAutocomplete';
3
+ const TextFieldBaseStyles = () => {
4
+ return {};
5
+ };
6
+ export const StyledDynamicAutocomplete = styled(DynamicAutocomplete)(TextFieldBaseStyles);
@@ -0,0 +1,2 @@
1
+ import { StyledDynamicAutocomplete } from './DynamicAutocomplete.styles';
2
+ export { StyledDynamicAutocomplete as DynamicAutocomplete };
@@ -0,0 +1,2 @@
1
+ import { StyledDynamicAutocomplete } from './DynamicAutocomplete.styles';
2
+ export { StyledDynamicAutocomplete as DynamicAutocomplete };
@@ -1,4 +1,5 @@
1
1
  export * from './FileUploader';
2
+ export * from './DynamicAutocomplete';
2
3
  export * from './Autocomplete';
3
4
  export * from './CustomComponentWrapper.styles';
4
5
  export * from './CustomComponentWrapper';
@@ -1,4 +1,5 @@
1
1
  export * from './FileUploader';
2
+ export * from './DynamicAutocomplete';
2
3
  export * from './Autocomplete';
3
4
  export * from './CustomComponentWrapper.styles';
4
5
  export * from './CustomComponentWrapper';
@@ -0,0 +1,22 @@
1
+ /// <reference types="react" />
2
+ import { PropertySpec } from '../../../api';
3
+ import { ScalarEntityValue } from '../../../entity';
4
+ import { NullableFormFieldFactoryChoices } from '../FormFieldFactory';
5
+ import { SelectOptionsType } from 'entities/EntityInterface';
6
+ import { FormOnChangeEvent } from 'entities/DefaultEntityBehavior/Form/Form';
7
+ declare type DynamicAutocompleteFactoryPropsType = {
8
+ fld: string;
9
+ property: PropertySpec;
10
+ disabled: boolean;
11
+ multiSelect: boolean;
12
+ value: ScalarEntityValue | Array<ScalarEntityValue>;
13
+ hasChanged: boolean;
14
+ error: React.ReactNode;
15
+ touched: boolean | undefined;
16
+ changeHandler: (event: FormOnChangeEvent) => void;
17
+ choices: NullableFormFieldFactoryChoices;
18
+ handleBlur: (event: React.FocusEvent) => void;
19
+ selectOptions: (() => Promise<SelectOptionsType>) | undefined;
20
+ };
21
+ export declare const DynamicAutocompleteFactory: (props: DynamicAutocompleteFactoryPropsType) => JSX.Element;
22
+ export {};
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DynamicAutocomplete } from '../../Field/DynamicAutocomplete';
3
+ export const DynamicAutocompleteFactory = (props) => {
4
+ const { selectOptions, fld, disabled, multiSelect, value, hasChanged, error, touched, property, changeHandler, handleBlur, } = props;
5
+ return (_jsx(DynamicAutocomplete, { name: fld, label: property.label, value: value, multiple: multiSelect, nullOption: property.null, required: property.required, disabled: disabled, onBlur: handleBlur, error: touched && Boolean(error), errorMsg: touched && error, helperText: property.helpText, hasChanged: hasChanged, onChange: changeHandler, selectOptions: selectOptions }));
6
+ };
@@ -1,3 +1,4 @@
1
+ import { DynamicAutocompleteFactory } from './DynamicAutocompleteFactory';
1
2
  import { AutocompleteFactory } from './AutocompleteFactory';
2
3
  import { DateFactory } from './DateFactory';
3
4
  import { DateTimeFactory } from './DateTimeFactory';
@@ -11,4 +12,4 @@ import { SwitchFactory } from './SwitchFactory';
11
12
  import { TextareaFactory } from './TextareaFactory';
12
13
  import { TimeFactory } from './TimeFactory';
13
14
  import { ColorFactory } from './ColorFactory';
14
- export { AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, };
15
+ export { DynamicAutocompleteFactory, AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, };
@@ -1,3 +1,4 @@
1
+ import { DynamicAutocompleteFactory } from './DynamicAutocompleteFactory';
1
2
  import { AutocompleteFactory } from './AutocompleteFactory';
2
3
  import { DateFactory } from './DateFactory';
3
4
  import { DateTimeFactory } from './DateTimeFactory';
@@ -11,4 +12,4 @@ import { SwitchFactory } from './SwitchFactory';
11
12
  import { TextareaFactory } from './TextareaFactory';
12
13
  import { TimeFactory } from './TimeFactory';
13
14
  import { ColorFactory } from './ColorFactory';
14
- export { AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, };
15
+ export { DynamicAutocompleteFactory, AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, };
@@ -12,6 +12,7 @@ export default class FormFieldFactory {
12
12
  private handleBlur;
13
13
  private divRef?;
14
14
  constructor(entityService: EntityService, formik: useFormikType, changeHandler: (event: FormOnChangeEvent) => void, handleBlur: (event: React.FocusEvent) => void, divRef?: React.RefObject<HTMLDivElement> | undefined);
15
+ private getDynamicSelectOptions;
15
16
  getFormField(fld: string, choices: NullableFormFieldFactoryChoices, readOnly?: boolean): JSX.Element | null;
16
17
  createByPropertySpec(fld: string, property: PropertySpec, choices: NullableFormFieldFactoryChoices, readOnly?: boolean): JSX.Element | null;
17
18
  getProperty(fld: string): PropertySpec | null;
@@ -3,7 +3,8 @@ import { InputAdornment, } from '@mui/material';
3
3
  import React from 'react';
4
4
  import { isPropertyEmbeddable, isPropertyFk, isPropertyScalar, } from '../../api/ParsedApiSpecInterface';
5
5
  import { CustomFunctionComponentContext, } from '../../form/Field/CustomComponentWrapper';
6
- import { AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, } from './Factory/index';
6
+ import { DynamicAutocompleteFactory, AutocompleteFactory, DateFactory, DateTimeFactory, DropdownFactory, FileUploadFactory, InputTextFactory, MultilangFactory, NumberFactory, PasswordFactory, SwitchFactory, TextareaFactory, TimeFactory, ColorFactory, } from './Factory/index';
7
+ import { StoreContainer } from '../../../store';
7
8
  export default class FormFieldFactory {
8
9
  constructor(entityService, formik, changeHandler, handleBlur, divRef) {
9
10
  this.entityService = entityService;
@@ -12,6 +13,18 @@ export default class FormFieldFactory {
12
13
  this.handleBlur = handleBlur;
13
14
  this.divRef = divRef;
14
15
  }
16
+ getDynamicSelectOptions(property) {
17
+ var _a;
18
+ if (!isPropertyFk(property)) {
19
+ return undefined;
20
+ }
21
+ const entities = StoreContainer.store.getState().entities.entities;
22
+ const entityName = property.$ref.replace('#/definitions/', '');
23
+ if (!((_a = entities[entityName]) === null || _a === void 0 ? void 0 : _a.dynamicSelectOptions)) {
24
+ return undefined;
25
+ }
26
+ return entities[entityName].selectOptions;
27
+ }
15
28
  getFormField(fld, choices, readOnly = false) {
16
29
  const property = this.getProperty(fld);
17
30
  if (!property) {
@@ -34,6 +47,10 @@ export default class FormFieldFactory {
34
47
  .component;
35
48
  return (_jsx(PropertyComponent, { _context: CustomFunctionComponentContext.write, _columnName: fld, readOnly: readOnly, formik: this.formik, values: this.formik.values, choices: choices, property: property, disabled: disabled, changeHandler: this.changeHandler, onBlur: this.handleBlur, formFieldFactory: this }));
36
49
  }
50
+ const dynamicSelectOptions = this.getDynamicSelectOptions(property);
51
+ if (dynamicSelectOptions) {
52
+ return (_jsx(DynamicAutocompleteFactory, { fld: fld, property: property, disabled: disabled, multiSelect: multiSelect, value: value, hasChanged: hasChanged, error: error, touched: touched, selectOptions: dynamicSelectOptions, choices: choices, changeHandler: this.changeHandler, handleBlur: this.handleBlur }));
53
+ }
37
54
  if (isPropertyFk(property) || multiSelect) {
38
55
  return (_jsx(AutocompleteFactory, { fld: fld, property: property, disabled: disabled, multiSelect: multiSelect, value: value, hasChanged: hasChanged, error: error, touched: touched, choices: choices, changeHandler: this.changeHandler, handleBlur: this.handleBlur }));
39
56
  }
@@ -40,6 +40,8 @@
40
40
  "Starts with": "empieza por",
41
41
  "This change will affect": "Aquest canvi afectarà",
42
42
  "True": "Verdadero",
43
+ "Type to load more options": "Escriu per carregar més opcions",
44
+ "Type to search": "Escriu per cercar",
43
45
  "Upload image": "Subir imagen",
44
46
  "Username": "Usuari",
45
47
  "Validation error": "Error de validación",
@@ -40,6 +40,8 @@
40
40
  "Starts with": "Starts with",
41
41
  "This change will affect": "This change will affect",
42
42
  "True": "True",
43
+ "Type to load more options": "Type to load more options",
44
+ "Type to search": "Type to search",
43
45
  "Upload image": "Upload image",
44
46
  "Username": "Username",
45
47
  "Validation error": "Validation error",
@@ -48,7 +50,7 @@
48
50
  "Yes, delete it": "Yes, delete it",
49
51
  "You are about to remove": "You are about to remove",
50
52
  "You are about to update": "You are about to update",
51
- "You havent created any {{entity}} yet.": "You havent created any {{entity}} yet.",
53
+ "You haven't created any {{entity}} yet.": "You haven't created any {{entity}} yet.",
52
54
  "entities": "entities",
53
55
  "invalid pattern": "invalid pattern",
54
56
  "required value": "required value",
@@ -40,6 +40,8 @@
40
40
  "Starts with": "empieza por",
41
41
  "This change will affect": "Este cambio afectará",
42
42
  "True": "Verdadero",
43
+ "Type to load more options": "Escribe para cargar más opciones",
44
+ "Type to search": "Escribe para buscar",
43
45
  "Upload image": "Subir imagen",
44
46
  "Username": "Usuario",
45
47
  "Validation error": "Error de validación",
@@ -48,7 +50,7 @@
48
50
  "Yes, delete it": "Si, eliminar",
49
51
  "You are about to remove": "Estás a punto de eliminar",
50
52
  "You are about to update": "Estás a punto de actualizar",
51
- "You havent created any {{entity}} yet.": "Aún no has creado ningún {{entity}}",
53
+ "You haven't created any {{entity}} yet.": "Aún no has creado ningún {{entity}}",
52
54
  "entities": "entidades",
53
55
  "invalid pattern": "Patrón invalido",
54
56
  "required value": "valor requerido",
@@ -40,6 +40,8 @@
40
40
  "Starts with": "Starts with",
41
41
  "This change will affect": "Questa modifica influirà",
42
42
  "True": "True",
43
+ "Type to load more options": "Digita per caricare più opzioni",
44
+ "Type to search": "Digita per cercare",
43
45
  "Upload image": "Upload image",
44
46
  "Username": "Username",
45
47
  "Validation error": "Validation error",