@ansible/ansible-ui-framework 0.0.190

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/cjs/framework/BulkActionDialog.js +217 -0
  3. package/cjs/framework/BulkProgressDialog.js +240 -0
  4. package/cjs/framework/FilterDrawer.js +64 -0
  5. package/cjs/framework/PageBody.js +47 -0
  6. package/cjs/framework/PageCatalog.js +178 -0
  7. package/cjs/framework/PageCells.js +141 -0
  8. package/cjs/framework/PageColumnModal.js +130 -0
  9. package/cjs/framework/PageDataList.js +61 -0
  10. package/cjs/framework/PageDialog.js +28 -0
  11. package/cjs/framework/PageForm.js +376 -0
  12. package/cjs/framework/PageFramework.js +11 -0
  13. package/cjs/framework/PageHeader.js +96 -0
  14. package/cjs/framework/PageLayout.js +41 -0
  15. package/cjs/framework/PagePagination.js +28 -0
  16. package/cjs/framework/PageTable.js +205 -0
  17. package/cjs/framework/PageTabs.js +82 -0
  18. package/cjs/framework/PageToolbar.js +209 -0
  19. package/cjs/framework/Settings.js +122 -0
  20. package/cjs/framework/TypedActions.js +303 -0
  21. package/cjs/framework/components/BulkSelector.js +89 -0
  22. package/cjs/framework/components/Collapse.js +22 -0
  23. package/cjs/framework/components/DetailInfo.js +23 -0
  24. package/cjs/framework/components/Details.js +88 -0
  25. package/cjs/framework/components/Dotted.js +19 -0
  26. package/cjs/framework/components/DropdownControlled.js +28 -0
  27. package/cjs/framework/components/ErrorBoundary.js +45 -0
  28. package/cjs/framework/components/Grid.js +64 -0
  29. package/cjs/framework/components/Help.js +24 -0
  30. package/cjs/framework/components/IconWrapper.js +55 -0
  31. package/cjs/framework/components/LoadingPage.js +14 -0
  32. package/cjs/framework/components/Masonry.js +113 -0
  33. package/cjs/framework/components/Scrollable.js +87 -0
  34. package/cjs/framework/components/SingleSelect.js +70 -0
  35. package/cjs/framework/components/patternfly-colors.js +32 -0
  36. package/cjs/framework/components/useBreakPoint.js +145 -0
  37. package/cjs/framework/components/useOpen.js +36 -0
  38. package/cjs/framework/components/useWindowLocation.js +70 -0
  39. package/cjs/framework/index.js +39 -0
  40. package/cjs/framework/useFrameworkTranslations.js +38 -0
  41. package/cjs/framework/useSelectDialog.js +81 -0
  42. package/cjs/framework/useSelectMultipleDialog.js +62 -0
  43. package/cjs/framework/useTableItems.js +485 -0
  44. package/cjs/framework/useView.js +155 -0
  45. package/cjs/framework/utils/compare.js +59 -0
  46. package/cjs/framework/utils/download-file.js +23 -0
  47. package/cjs/framework/utils/random-string.js +17 -0
  48. package/cjs/frontend/controller/access/organizations/Organization.js +2 -0
  49. package/mjs/framework/BulkActionDialog.d.ts +25 -0
  50. package/mjs/framework/BulkActionDialog.js +104 -0
  51. package/mjs/framework/BulkProgressDialog.d.ts +20 -0
  52. package/mjs/framework/BulkProgressDialog.js +131 -0
  53. package/mjs/framework/FilterDrawer.d.ts +8 -0
  54. package/mjs/framework/FilterDrawer.js +24 -0
  55. package/mjs/framework/PageBody.d.ts +4 -0
  56. package/mjs/framework/PageBody.js +29 -0
  57. package/mjs/framework/PageCatalog.d.ts +113 -0
  58. package/mjs/framework/PageCatalog.js +140 -0
  59. package/mjs/framework/PageCells.d.ts +35 -0
  60. package/mjs/framework/PageCells.js +102 -0
  61. package/mjs/framework/PageColumnModal.d.ts +7 -0
  62. package/mjs/framework/PageColumnModal.js +64 -0
  63. package/mjs/framework/PageDataList.d.ts +46 -0
  64. package/mjs/framework/PageDataList.js +45 -0
  65. package/mjs/framework/PageDialog.d.ts +10 -0
  66. package/mjs/framework/PageDialog.js +12 -0
  67. package/mjs/framework/PageForm.d.ts +147 -0
  68. package/mjs/framework/PageForm.js +316 -0
  69. package/mjs/framework/PageFramework.d.ts +4 -0
  70. package/mjs/framework/PageFramework.js +7 -0
  71. package/mjs/framework/PageHeader.d.ts +45 -0
  72. package/mjs/framework/PageHeader.js +80 -0
  73. package/mjs/framework/PageLayout.d.ts +15 -0
  74. package/mjs/framework/PageLayout.js +23 -0
  75. package/mjs/framework/PagePagination.d.ts +10 -0
  76. package/mjs/framework/PagePagination.js +22 -0
  77. package/mjs/framework/PageTable.d.ts +68 -0
  78. package/mjs/framework/PageTable.js +170 -0
  79. package/mjs/framework/PageTabs.d.ts +15 -0
  80. package/mjs/framework/PageTabs.js +45 -0
  81. package/mjs/framework/PageToolbar.d.ts +57 -0
  82. package/mjs/framework/PageToolbar.js +148 -0
  83. package/mjs/framework/Settings.d.ts +19 -0
  84. package/mjs/framework/Settings.js +87 -0
  85. package/mjs/framework/TypedActions.d.ts +80 -0
  86. package/mjs/framework/TypedActions.js +251 -0
  87. package/mjs/framework/components/BulkSelector.d.ts +11 -0
  88. package/mjs/framework/components/BulkSelector.js +56 -0
  89. package/mjs/framework/components/Collapse.d.ts +5 -0
  90. package/mjs/framework/components/Collapse.js +7 -0
  91. package/mjs/framework/components/DetailInfo.d.ts +5 -0
  92. package/mjs/framework/components/DetailInfo.js +8 -0
  93. package/mjs/framework/components/Details.d.ts +38 -0
  94. package/mjs/framework/components/Details.js +68 -0
  95. package/mjs/framework/components/Dotted.d.ts +4 -0
  96. package/mjs/framework/components/Dotted.js +4 -0
  97. package/mjs/framework/components/DropdownControlled.d.ts +4 -0
  98. package/mjs/framework/components/DropdownControlled.js +8 -0
  99. package/mjs/framework/components/ErrorBoundary.d.ts +15 -0
  100. package/mjs/framework/components/ErrorBoundary.js +25 -0
  101. package/mjs/framework/components/Grid.d.ts +6 -0
  102. package/mjs/framework/components/Grid.js +27 -0
  103. package/mjs/framework/components/Help.d.ts +5 -0
  104. package/mjs/framework/components/Help.js +9 -0
  105. package/mjs/framework/components/IconWrapper.d.ts +8 -0
  106. package/mjs/framework/components/IconWrapper.js +40 -0
  107. package/mjs/framework/components/LoadingPage.d.ts +6 -0
  108. package/mjs/framework/components/LoadingPage.js +9 -0
  109. package/mjs/framework/components/Masonry.d.ts +6 -0
  110. package/mjs/framework/components/Masonry.js +69 -0
  111. package/mjs/framework/components/Scrollable.d.ts +7 -0
  112. package/mjs/framework/components/Scrollable.js +60 -0
  113. package/mjs/framework/components/SingleSelect.d.ts +18 -0
  114. package/mjs/framework/components/SingleSelect.js +37 -0
  115. package/mjs/framework/components/patternfly-colors.d.ts +13 -0
  116. package/mjs/framework/components/patternfly-colors.js +28 -0
  117. package/mjs/framework/components/useBreakPoint.d.ts +5 -0
  118. package/mjs/framework/components/useBreakPoint.js +118 -0
  119. package/mjs/framework/components/useOpen.d.ts +4 -0
  120. package/mjs/framework/components/useOpen.js +16 -0
  121. package/mjs/framework/components/useWindowLocation.d.ts +6 -0
  122. package/mjs/framework/components/useWindowLocation.js +48 -0
  123. package/mjs/framework/index.d.ts +23 -0
  124. package/mjs/framework/index.js +23 -0
  125. package/mjs/framework/useFrameworkTranslations.d.ts +17 -0
  126. package/mjs/framework/useFrameworkTranslations.js +22 -0
  127. package/mjs/framework/useSelectDialog.d.ts +30 -0
  128. package/mjs/framework/useSelectDialog.js +49 -0
  129. package/mjs/framework/useSelectMultipleDialog.d.ts +21 -0
  130. package/mjs/framework/useSelectMultipleDialog.js +29 -0
  131. package/mjs/framework/useTableItems.d.ts +76 -0
  132. package/mjs/framework/useTableItems.js +371 -0
  133. package/mjs/framework/useView.d.ts +15 -0
  134. package/mjs/framework/useView.js +108 -0
  135. package/mjs/framework/utils/compare.d.ts +3 -0
  136. package/mjs/framework/utils/compare.js +53 -0
  137. package/mjs/framework/utils/download-file.d.ts +2 -0
  138. package/mjs/framework/utils/download-file.js +18 -0
  139. package/mjs/framework/utils/random-string.d.ts +1 -0
  140. package/mjs/framework/utils/random-string.js +12 -0
  141. package/mjs/frontend/controller/access/organizations/Organization.d.ts +44 -0
  142. package/mjs/frontend/controller/access/organizations/Organization.js +1 -0
  143. package/package.json +39 -0
@@ -0,0 +1,316 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { ajvResolver } from '@hookform/resolvers/ajv';
3
+ import { ActionGroup, Alert, Button, Checkbox, Flex, FlexItem, Form, FormGroup, FormSection, Grid, InputGroup, Menu, MenuItem, PageSection, Select, SelectGroup, SelectOption, SelectVariant, Slider, Switch, TextArea, TextInput, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, Tooltip, } from '@patternfly/react-core';
4
+ import { CaretDownIcon, EyeIcon, EyeSlashIcon, SearchIcon } from '@patternfly/react-icons';
5
+ import deepEqual from 'fast-deep-equal';
6
+ import { Children, Fragment, isValidElement, useCallback, useContext, useState, } from 'react';
7
+ import { FormProvider, useController, useForm, useFormContext, useFormState, } from 'react-hook-form';
8
+ import { Collapse, PageHeader, useBreakpoint } from '.';
9
+ import { Scrollable } from './components/Scrollable';
10
+ import { SettingsContext } from './Settings';
11
+ export function FormPage(props) {
12
+ // const methods = useForm<PartialDeep<T>>({
13
+ // defaultValues: props.defaultValues,
14
+ // resolver: ajvResolver(props.schema, { strict: false }),
15
+ // })
16
+ const children = Children.toArray(props.children);
17
+ const inputs = children.filter((child) => {
18
+ if (!isValidElement(child))
19
+ return false;
20
+ if (child.type === FormPageAlerts)
21
+ return false;
22
+ if (child.type === FormPageButtons)
23
+ return false;
24
+ return true;
25
+ });
26
+ const buttons = children.find((child) => {
27
+ if (!isValidElement(child))
28
+ return false;
29
+ if (child.type === FormPageButtons)
30
+ return true;
31
+ return false;
32
+ });
33
+ const [settings] = useContext(SettingsContext);
34
+ return (_jsxs(_Fragment, { children: [!props.hideHeader && _jsx(PageHeader, { ...props }), _jsxs(Form
35
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
36
+ , {
37
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
38
+ onSubmit: props.form.handleSubmit(props.onSubmit), isHorizontal: props.isVertical ? false : settings.formLayout === 'horizontal', style: {
39
+ display: 'flex',
40
+ flexDirection: 'column',
41
+ flexGrow: 1,
42
+ overflow: 'hidden',
43
+ }, children: [_jsx(Scrollable, { style: { height: '100%', flexGrow: 1 }, children: _jsx(PageSection, { padding: { default: props.noPadding ? 'noPadding' : 'padding' }, isWidthLimited: true, children: _jsx(FormSection, { children: inputs }) }) }), buttons] })] }));
44
+ }
45
+ export function FormPageAlerts() {
46
+ const { errors } = useFormState();
47
+ const isMd = useBreakpoint('md');
48
+ return (_jsx(Fragment, { children: errors && Object.keys(errors).length > 0 && (_jsx(Alert, { title: "Please fix validation errors.", isInline: true, style: { width: '100%', paddingLeft: isMd ? 190 : undefined }, variant: "danger" })) }));
49
+ }
50
+ export function FormPageButtons(props) {
51
+ const { errors } = useFormState();
52
+ return (_jsxs("div", { children: [_jsx(FormPageAlerts, {}), _jsx(PageSection, { isFilled: true, style: {
53
+ display: 'flex',
54
+ flexDirection: 'column',
55
+ maxHeight: '100%',
56
+ borderTop: 'thin solid var(--pf-global--BorderColor--100)',
57
+ }, variant: "light", children: _jsxs(ActionGroup, { style: { marginTop: 0 }, children: [errors && Object.keys(errors).length > 0 ? (_jsx(Tooltip, { content: 'Please fix validation errors', children: _jsx(Button, { type: "submit", isAriaDisabled: true, children: props.submitText }) })) : (_jsx(Button, { type: "submit", children: props.submitText })), _jsx(Button, { type: "button", variant: "link", onClick: props.onCancel, children: props.cancelText })] }) })] }));
58
+ }
59
+ export function FormInputCheckbox(props) {
60
+ const { control } = useFormContext();
61
+ const { field } = useController({ control, name: props.name });
62
+ const id = props.name;
63
+ return (_jsx(Checkbox, { label: props.label, id: id, "aria-describedby": `${id}-helper`, description: props.description, body: field.value ? props.body : undefined, ...field, isChecked: !!field.value }));
64
+ }
65
+ export function FormTextInput(props) {
66
+ const { register, formState: { isSubmitting }, } = useFormContext();
67
+ const registration = register(props.name);
68
+ const { fieldState } = useController({ name: props.name });
69
+ const error = fieldState.error;
70
+ const id = props.id ?? props.name;
71
+ const [showSecret, setShowSecret] = useState(false);
72
+ return (_jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperText: props.helperText, isRequired: props.required, validated: error?.message ? 'error' : undefined, helperTextInvalid: error?.message, children: _jsxs(InputGroup, { children: [_jsx(TextInput, { id: id, type: props.secret && !showSecret ? 'password' : 'text', "aria-describedby": `${id}-form-group`, isRequired: props.required, validated: error?.message ? 'error' : undefined, autoFocus: props.autoFocus, placeholder: props.placeholder, ...registration, onChange: (v, e) => {
73
+ void registration.onChange(e);
74
+ },
75
+ // innerRef={registration.ref}
76
+ isReadOnly: isSubmitting }), props.secret && (_jsx(Button, { variant: "control", onClick: () => setShowSecret(!showSecret), "aria-label": "Options menu", isDisabled: isSubmitting, children: showSecret ? _jsx(EyeIcon, {}) : _jsx(EyeSlashIcon, {}) }))] }) }));
77
+ }
78
+ export function FormTextArea(props) {
79
+ const { register, formState: { isSubmitting }, } = useFormContext();
80
+ const registration = register(props.name);
81
+ const { fieldState } = useController({ name: props.name });
82
+ const error = fieldState.error;
83
+ const id = props.id ?? props.name;
84
+ return (_jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperText: props.helperText, isRequired: props.required, validated: error?.message ? 'error' : undefined, helperTextInvalid: error?.message, children: _jsx(TextArea, { id: id, type: props.secret ? 'password' : 'text', "aria-describedby": `${id}-form-group`, isRequired: props.required, validated: error?.message ? 'error' : undefined, autoFocus: props.autoFocus, placeholder: props.placeholder, ...registration, onChange: (v, e) => void registration.onChange(e), resizeOrientation: "vertical", isReadOnly: isSubmitting }) }));
85
+ }
86
+ export function FormNumberInput(props) {
87
+ const { formState: { isSubmitting }, } = useFormContext();
88
+ const { field, fieldState } = useController({ name: props.name });
89
+ const error = fieldState.error;
90
+ const id = props.id ?? props.name;
91
+ const max = props.max ?? 100;
92
+ const min = props.min ?? 1;
93
+ const value = Number(field.value);
94
+ return (_jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperText: props.helperText, isRequired: props.required, validated: error?.message ? 'error' : undefined, helperTextInvalid: error?.message, children: _jsxs(Flex, { alignItems: { default: 'alignItemsFlexStart' }, children: [_jsxs(Flex, { alignItems: { default: 'alignItemsFlexStart' }, spaceItems: { default: 'spaceItemsSm' }, children: [_jsx(FlexItem, { style: { paddingTop: 6, minWidth: 20, textAlign: 'right' }, children: Math.floor((max - min) * value + min) }), props.valueLabel && (_jsx(FlexItem, { style: { paddingTop: 6, minWidth: 40 }, children: props.valueLabel }))] }), _jsx(FlexItem, { grow: { default: 'grow' }, children: _jsx(Slider, { id: id, "aria-describedby": `${id}-form-group`,
95
+ // isRequired={props.required}
96
+ // validated={error?.message ? 'error' : undefined}
97
+ autoFocus: props.autoFocus,
98
+ // {...registration}
99
+ value: (max - min) * value + min, onChange: (v) => field.onChange((v - min) / (max - min)), max: max, min: min,
100
+ // innerRef={registration.ref}
101
+ isDisabled: isSubmitting, showBoundaries: false }) })] }) }));
102
+ }
103
+ export function FormBooleanInput(props) {
104
+ const { formState: { isSubmitting }, } = useFormContext();
105
+ const { field, fieldState } = useController({ name: props.name });
106
+ const error = fieldState.error;
107
+ const id = props.id ?? props.name;
108
+ return (_jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperText: props.helperText, isRequired: props.required, validated: error?.message ? 'error' : undefined, helperTextInvalid: error?.message, children: _jsx(Switch, { id: id, "aria-describedby": `${id}-form-group`,
109
+ // isRequired={props.required}
110
+ // validated={error?.message ? 'error' : undefined}
111
+ autoFocus: props.autoFocus,
112
+ // placeholder={props.placeholder}
113
+ // {...registration}
114
+ isChecked: typeof field.value === 'boolean' ? field.value : false, onChange: (e) => field.onChange(e),
115
+ // innerRef={registration.ref}
116
+ isDisabled: isSubmitting }) }));
117
+ }
118
+ export function FormSelect(props) {
119
+ const { field, fieldState: { error: fieldError }, } = useController({ name: props.name });
120
+ const [open, setOpen] = useState(false);
121
+ const id = props.id ?? props.name;
122
+ const error = fieldError !== undefined && fieldError.message;
123
+ const { options } = props;
124
+ options.sort((l, r) => {
125
+ if ((l.group ?? '') < (r.group ?? ''))
126
+ return -1;
127
+ if ((l.group ?? '') > (r.group ?? ''))
128
+ return 1;
129
+ if (l.label < r.label)
130
+ return -1;
131
+ if (l.label > r.label)
132
+ return 1;
133
+ return 0;
134
+ });
135
+ const selectedIndex = options.findIndex((option) => deepEqual(option.value, field.value));
136
+ const groups = options.reduce((groups, option) => {
137
+ const group = option.group ?? '';
138
+ let optionsArray = groups[group];
139
+ if (!optionsArray) {
140
+ optionsArray = [];
141
+ groups[group] = optionsArray;
142
+ }
143
+ optionsArray.push(option);
144
+ return groups;
145
+ }, {});
146
+ const isGrouped = Object.keys(groups).length > 1 ||
147
+ (Object.keys(groups).length === 1 && Object.keys(groups)[0] !== '');
148
+ const onSelect = useCallback((_event, value) => {
149
+ if (typeof value !== 'string') {
150
+ value = value.toString();
151
+ }
152
+ const selectedIndex = Number(value);
153
+ const selected = options[selectedIndex].value;
154
+ field.onChange(selected);
155
+ setOpen(false);
156
+ }, [field, options]);
157
+ let index = 0;
158
+ return (_jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperTextInvalid: error, helperText: props.help, isRequired: props.required, validated: error ? 'error' : undefined, children: _jsx(Select, { id: id, variant: SelectVariant.single, "aria-describedby": `${id}-helper`, validated: error ? 'error' : undefined, ...field, isOpen: open, onToggle: () => setOpen(!open), selections: selectedIndex === -1 ? '' : selectedIndex.toString(), onSelect: onSelect, isCreatable: props.create, isInputFilterPersisted: props.create, placeholderText: props.placeholder, isGrouped: isGrouped, footer: props.footer?.label && (_jsx(Button, { variant: "link", isInline: true, onClick: () => {
159
+ setOpen(false);
160
+ props.footer?.click?.();
161
+ }, children: props.footer.label })), maxHeight: 280, children: !isGrouped
162
+ ? options.map((option, index) => (_jsx(SelectOption, { value: index.toString(), label: option.label, description: option.description, children: option.label }, index)))
163
+ : Object.keys(groups).map((group) => (_jsx(SelectGroup, { label: group, children: groups[group].map((option) => (_jsx(SelectOption, { value: (index++).toString(), label: option.label, description: option.description, children: option.label }, index))) }, group))) }) }));
164
+ }
165
+ export function FormSelectInput(props) {
166
+ const { control } = useFormContext();
167
+ const { field, fieldState: { error }, } = useController({ control, name: props.name });
168
+ const menuItems = Children.toArray(props.children)
169
+ .filter((child) => isValidElement(child) && child.type === SelectOption)
170
+ .map((child) => {
171
+ if (isValidElement(child) && child.type === SelectOption) {
172
+ return (_jsx(MenuItem, { children: child.props.children }, child.props.value));
173
+ }
174
+ return _jsx(_Fragment, {});
175
+ });
176
+ const [open, setOpen] = useState(false);
177
+ const id = props.name;
178
+ let errorMessage;
179
+ switch (error?.type) {
180
+ case 'required':
181
+ errorMessage = props.label + ' is required.';
182
+ break;
183
+ default:
184
+ errorMessage = error?.type;
185
+ break;
186
+ }
187
+ return (_jsx(FormGroup, { fieldId: id, label: props.label, helperTextInvalid: errorMessage, helperText: props.helperText, isRequired: props.required, validated: errorMessage ? 'error' : undefined, children: _jsxs(TextInputGroup, { children: [_jsx(TextInputGroupMain, { ...field }), _jsx(TextInputGroupUtilities, { children: _jsx(Button, { variant: "plain", onClick: () => setOpen(!open), "aria-label": "Options menu", children: _jsx(CaretDownIcon, {}) }) }), open && (_jsx(Menu, { style: { position: 'absolute', right: 0, top: 36, width: '100%' }, children: menuItems }))] }) }));
188
+ }
189
+ export function FormTextSelect(props) {
190
+ const { register, setValue, formState: { isSubmitting }, } = useFormContext();
191
+ const registration = register(props.name);
192
+ const { fieldState } = useController({ name: props.name });
193
+ const error = fieldState.error;
194
+ let id = props.id ?? props.name;
195
+ id = id.split('.').join('-');
196
+ return (_jsx(Fragment, { children: _jsx(FormGroup, { id: `${id}-form-group`, fieldId: id, label: props.label, helperText: props.helperText, isRequired: props.required, validated: error?.message ? 'error' : undefined, helperTextInvalid: error?.message, children: _jsxs(InputGroup, { children: [_jsx(TextInput, { id: id, type: props.secret ? 'password' : 'text', "aria-describedby": `${id}-form-group`, isRequired: props.required, validated: error?.message ? 'error' : undefined, autoFocus: props.autoFocus, placeholder: props.placeholder, ...registration, onChange: (v, e) => {
197
+ void registration.onChange(e);
198
+ },
199
+ // innerRef={registration.ref}
200
+ isReadOnly: isSubmitting }), _jsx(Button, { variant: "control", onClick: () => props.selectOpen?.((item) => {
201
+ if (props.selectValue) {
202
+ const value = props.selectValue(item);
203
+ setValue(props.name, value, { shouldValidate: true });
204
+ }
205
+ }, props.selectTitle), "aria-label": "Options menu", isDisabled: isSubmitting, children: _jsx(SearchIcon, {}) })] }) }) }));
206
+ }
207
+ export function FormSchema(props) {
208
+ const { schema } = props;
209
+ const base = props.base ? props.base + '.' : '';
210
+ const p = [];
211
+ for (const propertyName in schema.properties) {
212
+ const property = schema.properties[propertyName];
213
+ switch (property) {
214
+ case true:
215
+ case false:
216
+ continue;
217
+ }
218
+ const title = typeof property.title === 'string' ? property.title : propertyName;
219
+ let placeholder = property.placeholder;
220
+ placeholder = typeof placeholder === 'string' ? placeholder : undefined;
221
+ const required = Array.isArray(schema.required) && schema.required.includes(propertyName);
222
+ switch (property.type) {
223
+ case 'string': {
224
+ switch (property.variant) {
225
+ case 'select': {
226
+ if ('options' in property) {
227
+ const formSelectProps = property;
228
+ p.push(_jsx(FormSelect, { name: base + propertyName, label: title, placeholder: placeholder, required: required, options: formSelectProps.options, footer: formSelectProps.footer }, base + propertyName));
229
+ }
230
+ else {
231
+ p.push(_jsx(FormTextSelect, { name: base + propertyName, label: title, placeholder: placeholder, required: required, selectTitle: property.selectTitle, selectValue: property.selectValue, selectOpen: property.selectOpen }, base + propertyName));
232
+ }
233
+ break;
234
+ }
235
+ case 'textarea':
236
+ p.push(_jsx(FormTextArea, { name: base + propertyName, label: title, placeholder: placeholder, required: required }, base + propertyName));
237
+ break;
238
+ case 'secret':
239
+ p.push(_jsx(FormTextInput, { name: base + propertyName, label: title, placeholder: placeholder, required: required, secret: true }, base + propertyName));
240
+ break;
241
+ default:
242
+ p.push(_jsx(FormTextInput, { name: base + propertyName, label: title, placeholder: placeholder, required: required }, base + propertyName));
243
+ break;
244
+ }
245
+ break;
246
+ }
247
+ case 'number': {
248
+ p.push(_jsx(FormNumberInput, { name: base + propertyName, label: title, required: required, min: property.min, max: property.max, valueLabel: property.valueLabel }, base + propertyName));
249
+ break;
250
+ }
251
+ case 'boolean': {
252
+ p.push(_jsx(FormBooleanInput, { name: base + propertyName, label: title, required: required }, base + propertyName));
253
+ break;
254
+ }
255
+ case 'object': {
256
+ p.push(_jsx(FormSchema, { schema: property, base: base + propertyName }, propertyName));
257
+ break;
258
+ }
259
+ }
260
+ }
261
+ return _jsx(_Fragment, { children: p });
262
+ }
263
+ export function PageForm(props) {
264
+ const { schema, defaultValue } = props;
265
+ const form = useForm({
266
+ defaultValues: defaultValue ?? {},
267
+ resolver: schema
268
+ ? ajvResolver(schema, { strict: false, addFormats: true })
269
+ : undefined,
270
+ });
271
+ const { handleSubmit, setError: setFieldError } = form;
272
+ const [error, setError] = useState('');
273
+ const isMd = useBreakpoint('md');
274
+ const [settings] = useContext(SettingsContext);
275
+ const isHorizontal = props.isVertical ? false : settings.formLayout === 'horizontal';
276
+ const multipleColumns = props.singleColumn ? false : settings.formColumns === 'multiple';
277
+ const sm = multipleColumns ? (isHorizontal ? 12 : 12) : 12;
278
+ const md = multipleColumns ? (isHorizontal ? 12 : 6) : 12;
279
+ const lg = multipleColumns ? (isHorizontal ? 6 : 6) : 12;
280
+ const xl = multipleColumns ? (isHorizontal ? 6 : 6) : 12;
281
+ const xl2 = multipleColumns ? (isHorizontal ? 4 : 4) : 12;
282
+ const maxWidth = multipleColumns ? undefined : isHorizontal ? 960 : 800;
283
+ return (
284
+ // <PageBody>
285
+ _jsx(FormProvider, { ...form, children: _jsxs(Form
286
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
287
+ , {
288
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
289
+ onSubmit: handleSubmit((data) => {
290
+ setError('');
291
+ return props.onSubmit(data, setError, setFieldError);
292
+ }), isHorizontal: isHorizontal, style: {
293
+ display: 'flex',
294
+ flexDirection: 'column',
295
+ flexGrow: 1,
296
+ overflow: props.disableScrolling ? undefined : 'hidden',
297
+ gap: 0,
298
+ }, children: [props.disableScrolling ? (_jsx(PageSection, { isFilled: true,
299
+ // padding={{ default: props.onCancel ? 'padding' : 'noPadding' }}
300
+ variant: "light", style: { maxWidth }, children: _jsxs(Grid, { hasGutter: true, span: 12, sm: sm, md: md, lg: lg, xl: xl, xl2: xl2, children: [props.schema && _jsx(FormSchema, { schema: props.schema }), props.children] }) })) : (_jsx(Scrollable, { style: { height: '100%', flexGrow: 1 }, children: _jsx(PageSection, { isFilled: true,
301
+ // padding={{ default: props.onCancel ? 'padding' : 'noPadding' }}
302
+ variant: "light", style: { maxWidth }, children: _jsxs(Grid, { hasGutter: true, span: 12, sm: sm, md: md, lg: lg, xl: xl, xl2: xl2, children: [props.schema && _jsx(FormSchema, { schema: props.schema }), props.children] }) }) })), _jsx(Collapse, { open: !!error, children: _jsx(Alert, { variant: "danger", title: error ?? '', isInline: true, style: { paddingLeft: isMd && props.onCancel ? 190 : undefined } }) }), props.onCancel ? (_jsx(PageSection, { isFilled: false, style: {
303
+ borderTop: 'thin solid var(--pf-global--BorderColor--100)',
304
+ backgroundColor: settings.theme === 'dark' ? 'var(--pf-global--BackgroundColor--400)' : undefined,
305
+ }, variant: "light", children: _jsxs(ActionGroup, { style: { marginTop: 0 }, children: [_jsx(PageFormSubmitButton, { children: props.submitText }), props.onCancel && (_jsx(PageFormCancelButton, { onCancel: props.onCancel, children: props.cancelText }))] }) })) : (_jsx(PageFormSubmitButton, { style: { marginTop: 48 }, children: props.submitText }))] }) })
306
+ // </PageBody>
307
+ );
308
+ }
309
+ export function PageFormSubmitButton(props) {
310
+ const { isSubmitting, errors } = useFormState();
311
+ const hasErrors = errors && Object.keys(errors).length > 0;
312
+ return (_jsx(Tooltip, { content: "Please fix errors", trigger: hasErrors ? undefined : 'manual', children: _jsx(Button, { type: "submit", isDisabled: isSubmitting, isLoading: isSubmitting, isDanger: hasErrors, variant: hasErrors ? 'secondary' : undefined, style: props.style, children: props.children }) }));
313
+ }
314
+ export function PageFormCancelButton(props) {
315
+ return (_jsx(Button, { type: "button", variant: "link", onClick: props.onCancel, children: props.children }));
316
+ }
@@ -0,0 +1,4 @@
1
+ import { ReactNode } from 'react';
2
+ export declare function PageFrameworkProvider(props: {
3
+ children: ReactNode;
4
+ }): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { PageDialogProvider } from './PageDialog';
3
+ import { SettingsProvider } from './Settings';
4
+ import { FrameworkTranslationsProvider } from './useFrameworkTranslations';
5
+ export function PageFrameworkProvider(props) {
6
+ return (_jsx(FrameworkTranslationsProvider, { children: _jsx(SettingsProvider, { children: _jsx(PageDialogProvider, { children: props.children }) }) }));
7
+ }
@@ -0,0 +1,45 @@
1
+ import { ReactNode } from 'react';
2
+ export interface ICatalogBreadcrumb {
3
+ id?: string;
4
+ label?: string;
5
+ to?: string;
6
+ target?: string;
7
+ component?: React.ElementType;
8
+ }
9
+ export interface PageHeaderProps {
10
+ navigation?: ReactNode;
11
+ breadcrumbs?: ICatalogBreadcrumb[];
12
+ title?: string;
13
+ titleHelpTitle?: string;
14
+ titleHelp?: string | string[];
15
+ titleDocLink?: string;
16
+ description?: string;
17
+ controls?: ReactNode;
18
+ headerActions?: ReactNode;
19
+ t?: (t: string) => string;
20
+ }
21
+ /**
22
+ * PageHeader enables the responsive layout of the header.
23
+ *
24
+ * @param {Breadcrumb[]} breadcrumbs - The breadcrumbs for the page.
25
+ * @param {string} title - The title of the page.
26
+ * @param {string} titleHelpTitle - The title of help popover.
27
+ * @param {ReactNode} titleHelp - The content for the help popover.
28
+ * @param {string} description - The description of the page.
29
+ * @param {ReactNode} controls - Support for extra page controls.
30
+ * @param {ReactNode} headerActions - The actions for the page.
31
+ *
32
+ * @example
33
+ * <Page>
34
+ * <PageLayout>
35
+ * <PageHeader
36
+ * breadcrumbs={[{ label: 'Home', to: '/home' }, { label: 'Page title' }]}
37
+ * title='Page title'
38
+ * description='Page description'
39
+ * headerActions={<PageActions actions={actions} />}
40
+ * />
41
+ * <PageBody />...</PageBody>
42
+ * </PageLayout>
43
+ * <Page>
44
+ */
45
+ export declare function PageHeader(props: PageHeaderProps): JSX.Element;
@@ -0,0 +1,80 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Breadcrumb, BreadcrumbItem, Button, Flex, FlexItem, PageNavigation, PageSection, PageSectionVariants, Popover, Skeleton, Stack, StackItem, Text, Title, Truncate, } from '@patternfly/react-core';
3
+ import { ExternalLinkAltIcon, OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
4
+ import { Fragment } from 'react';
5
+ import { useNavigate } from 'react-router-dom';
6
+ import { useBreakpoint } from './components/useBreakPoint';
7
+ import { useSettings } from './Settings';
8
+ function Breadcrumbs(props) {
9
+ const history = useNavigate();
10
+ if (!props.breadcrumbs)
11
+ return _jsx(Fragment, {});
12
+ return (_jsx(Breadcrumb, { style: props.style, children: props.breadcrumbs.map((breadcrumb) => {
13
+ if (!breadcrumb.label)
14
+ return _jsx(_Fragment, {});
15
+ return (_jsx(BreadcrumbItem, { id: breadcrumb.id, component: breadcrumb.component, onClick: breadcrumb.to ? () => breadcrumb.to && history(breadcrumb.to) : undefined, style: {
16
+ color: breadcrumb.to ? 'var(--pf-c-breadcrumb__link--Color)' : undefined,
17
+ cursor: breadcrumb.to ? 'pointer' : undefined,
18
+ }, isActive: breadcrumb.to === undefined, children: breadcrumb.label }, breadcrumb.id ?? breadcrumb.label));
19
+ }) }));
20
+ }
21
+ /**
22
+ * PageHeader enables the responsive layout of the header.
23
+ *
24
+ * @param {Breadcrumb[]} breadcrumbs - The breadcrumbs for the page.
25
+ * @param {string} title - The title of the page.
26
+ * @param {string} titleHelpTitle - The title of help popover.
27
+ * @param {ReactNode} titleHelp - The content for the help popover.
28
+ * @param {string} description - The description of the page.
29
+ * @param {ReactNode} controls - Support for extra page controls.
30
+ * @param {ReactNode} headerActions - The actions for the page.
31
+ *
32
+ * @example
33
+ * <Page>
34
+ * <PageLayout>
35
+ * <PageHeader
36
+ * breadcrumbs={[{ label: 'Home', to: '/home' }, { label: 'Page title' }]}
37
+ * title='Page title'
38
+ * description='Page description'
39
+ * headerActions={<PageActions actions={actions} />}
40
+ * />
41
+ * <PageBody />...</PageBody>
42
+ * </PageLayout>
43
+ * <Page>
44
+ */
45
+ export function PageHeader(props) {
46
+ const { navigation, breadcrumbs, title, description, controls, headerActions: pageActions, } = props;
47
+ const lg = useBreakpoint('lg');
48
+ const xl = useBreakpoint('xl');
49
+ const xxl = useBreakpoint('xxl');
50
+ const isMdOrLarger = useBreakpoint('md');
51
+ // const isSmLarger = useBreakpoint('sm')
52
+ const settings = useSettings();
53
+ let { t } = props;
54
+ t = t ? t : (t) => t;
55
+ return (_jsxs(_Fragment, { children: [navigation && (_jsx(PageSection, { variant: PageSectionVariants.light, style: {
56
+ paddingLeft: 0,
57
+ paddingTop: 0,
58
+ paddingBottom: 0,
59
+ borderBottom: settings.borders
60
+ ? 'thin solid var(--pf-global--BorderColor--100)'
61
+ : undefined,
62
+ backgroundColor: 'var(--pf-global--BackgroundColor--100)',
63
+ }, children: _jsx(Flex, { direction: { default: 'row' }, flexWrap: { default: 'nowrap' }, style: { maxWidth: '100%' }, children: _jsx(PageNavigation, { style: { paddingTop: 0, flexShrink: 1, flexGrow: 1 }, hasOverflowScroll: true, children: navigation }) }) })), (isMdOrLarger || !navigation) && (_jsx(PageSection, { variant: PageSectionVariants.light, style: {
64
+ paddingTop: breadcrumbs ? (xl ? 16 : 12) : xl ? 16 : 12,
65
+ paddingBottom: xl ? 20 : 12,
66
+ borderBottom: settings.borders
67
+ ? 'thin solid var(--pf-global--BorderColor--100)'
68
+ : undefined,
69
+ backgroundColor: settings.theme === 'dark'
70
+ ? xxl
71
+ ? 'var(--pf-global--BackgroundColor--300)'
72
+ : 'var(--pf-global--BackgroundColor--400)'
73
+ : undefined,
74
+ }, children: _jsxs(Flex, { flexWrap: { default: 'nowrap' }, alignItems: { default: 'alignItemsStretch' }, children: [_jsxs(FlexItem, { grow: { default: 'grow' }, children: [breadcrumbs && (_jsx(Breadcrumbs, { breadcrumbs: breadcrumbs, style: { paddingBottom: lg ? 6 : 4 } })), title ? (props.titleHelp ? (_jsx(Popover, { headerContent: props.titleHelpTitle, bodyContent: _jsxs(Stack, { hasGutter: true, children: [typeof props.titleHelp === 'string' ? (_jsx(StackItem, { children: props.titleHelp })) : (props.titleHelp.map((help, index) => (_jsx(StackItem, { children: help }, index)))), props.titleDocLink && (_jsx(StackItem, { children: _jsx(Button, { icon: _jsx(ExternalLinkAltIcon, {}), variant: "link", onClick: () => window.open(props.titleDocLink, '_blank'), isInline: true, children: t('Documentation') }) }))] }), position: "bottom-start", removeFindDomNode: true, children: _jsxs(Title, { headingLevel: "h1", children: [title, _jsx(Button, { variant: "link", style: {
75
+ padding: 0,
76
+ marginTop: 1,
77
+ marginLeft: 8,
78
+ verticalAlign: 'top',
79
+ }, children: _jsx(OutlinedQuestionCircleIcon, {}) })] }) })) : (_jsx(Title, { headingLevel: "h1", children: title }))) : (_jsx(Title, { headingLevel: "h1", children: _jsx(Skeleton, { width: "160px" }) })), isMdOrLarger && description && (_jsx(Text, { component: "p", style: { paddingTop: xl ? 4 : 2, opacity: 0.8 }, children: _jsx(Truncate, { content: description }) }))] }), title && (pageActions || controls) && (_jsxs(Flex, { direction: { default: 'column' }, spaceItems: { default: 'spaceItemsSm', xl: 'spaceItemsMd' }, justifyContent: { default: 'justifyContentCenter' }, children: [controls && _jsx(FlexItem, { grow: { default: 'grow' }, children: controls }), pageActions && _jsx(FlexItem, { children: pageActions })] }))] }) }))] }));
80
+ }
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * PageLayout enables the responsive layout of the page.
4
+ *
5
+ * @example
6
+ * <Page>
7
+ * <PageLayout>
8
+ * <PageHeader />
9
+ * <PageBody />...</PageBody>
10
+ * </PageLayout>
11
+ * <Page>
12
+ */
13
+ export declare function PageLayout(props: {
14
+ children: ReactNode;
15
+ }): JSX.Element;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from 'react-i18next';
3
+ import ErrorBoundary from './components/ErrorBoundary';
4
+ /**
5
+ * PageLayout enables the responsive layout of the page.
6
+ *
7
+ * @example
8
+ * <Page>
9
+ * <PageLayout>
10
+ * <PageHeader />
11
+ * <PageBody />...</PageBody>
12
+ * </PageLayout>
13
+ * <Page>
14
+ */
15
+ export function PageLayout(props) {
16
+ const { t } = useTranslation();
17
+ return (_jsx(ErrorBoundary, { message: t('Error'), children: _jsx("div", { style: {
18
+ display: 'flex',
19
+ flexDirection: 'column',
20
+ height: '100%',
21
+ maxHeight: '100%',
22
+ }, children: props.children }) }));
23
+ }
@@ -0,0 +1,10 @@
1
+ import { CSSProperties } from 'react';
2
+ export declare type PagePaginationProps = {
3
+ itemCount?: number;
4
+ page: number;
5
+ perPage: number;
6
+ setPage: (page: number) => void;
7
+ setPerPage: (perPage: number) => void;
8
+ style?: CSSProperties;
9
+ };
10
+ export declare function PagePagination(props: PagePaginationProps): JSX.Element;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Pagination, PaginationVariant } from '@patternfly/react-core';
3
+ import { useCallback } from 'react';
4
+ import { useBreakpoint } from './components/useBreakPoint';
5
+ import { useSettings } from './Settings';
6
+ export function PagePagination(props) {
7
+ const { setPage, setPerPage } = props;
8
+ const onSetPage = useCallback((_event, page) => setPage(page), [setPage]);
9
+ const onPerPageSelect = useCallback((_event, perPage) => setPerPage(perPage), [setPerPage]);
10
+ const sm = useBreakpoint('md');
11
+ const settings = useSettings();
12
+ return (_jsx(Pagination, { variant: PaginationVariant.bottom, itemCount: props.itemCount, page: props.page, perPage: props.perPage, onSetPage: onSetPage, onPerPageSelect: onPerPageSelect, style: {
13
+ ...props.style,
14
+ borderTop: 'thin solid var(--pf-global--BorderColor--100)',
15
+ boxShadow: 'none',
16
+ zIndex: 301,
17
+ marginTop: -1,
18
+ paddingTop: sm ? 6 : undefined,
19
+ paddingBottom: sm ? 6 : undefined,
20
+ backgroundColor: settings.theme === 'dark' ? 'var(--pf-global--BackgroundColor--300)' : undefined,
21
+ } }));
22
+ }
@@ -0,0 +1,68 @@
1
+ import { Dispatch, ReactNode, SetStateAction } from 'react';
2
+ import { PageHeaderProps } from './PageHeader';
3
+ import { IToolbarFilter } from './PageToolbar';
4
+ import { ITypedAction } from './TypedActions';
5
+ export declare type TablePageProps<T extends object> = PageHeaderProps & PageTableProps<T> & {
6
+ error?: Error;
7
+ };
8
+ export declare function TablePage<T extends object>(props: TablePageProps<T>): JSX.Element;
9
+ export declare type PageTableProps<T extends object> = {
10
+ keyFn: (item: T) => string | number;
11
+ itemCount?: number;
12
+ pageItems: T[] | undefined;
13
+ toolbarActions?: ITypedAction<T>[];
14
+ tableColumns: ITableColumn<T>[];
15
+ rowActions?: ITypedAction<T>[];
16
+ toolbarFilters?: IToolbarFilter[];
17
+ filters?: Record<string, string[]>;
18
+ setFilters?: Dispatch<SetStateAction<Record<string, string[]>>>;
19
+ clearAllFilters?: () => void;
20
+ sort?: string;
21
+ setSort?: (sort: string) => void;
22
+ sortDirection?: 'asc' | 'desc';
23
+ setSortDirection?: (sortDirection: 'asc' | 'desc') => void;
24
+ compact?: boolean;
25
+ page: number;
26
+ perPage: number;
27
+ setPage: (page: number) => void;
28
+ setPerPage: (perPage: number) => void;
29
+ autoHidePagination?: boolean;
30
+ isSelected?: (item: T) => boolean;
31
+ selectedItems?: T[];
32
+ selectItem?: (item: T) => void;
33
+ unselectItem?: (item: T) => void;
34
+ selectItems?: (items: T[]) => void;
35
+ unselectAll?: () => void;
36
+ onSelect?: (item: T) => void;
37
+ selectNoneText?: string;
38
+ errorStateTitle: string;
39
+ error?: Error;
40
+ emptyStateTitle: string;
41
+ emptyStateDescription?: string;
42
+ emptyStateButtonText?: string;
43
+ emptyStateButtonClick?: () => void;
44
+ t?: (t: string) => string;
45
+ showSelect?: boolean;
46
+ ColumnManagement?: boolean;
47
+ };
48
+ export declare function PageTable<T extends object>(props: PageTableProps<T>): JSX.Element;
49
+ declare type CellFn<T extends object> = (item: T) => ReactNode;
50
+ export interface ITableColumn<T extends object> {
51
+ id?: string;
52
+ header: string;
53
+ cell: CellFn<T>;
54
+ minWidth?: number;
55
+ maxWidth?: number;
56
+ enabled?: boolean;
57
+ sort?: string;
58
+ defaultSortDirection?: 'asc' | 'desc';
59
+ /**
60
+ * @deprecated The method should not be used
61
+ */
62
+ type?: 'labels' | 'progress' | 'date';
63
+ /**
64
+ * @deprecated The method should not be used
65
+ */
66
+ sortFn?: (l: T, r: T) => number;
67
+ }
68
+ export {};