{items && items.map((p, idx) =>
@@ -127,7 +132,7 @@ const StringListWithDefaultField = ({
className="flex-grow-1"
value={p.value}
onChange={({ target: { value } }) => setValue(p, value)}>
-
setDefault(p) }
>
diff --git a/ui/src/app/form/component/widgets/RadioWidget.js b/ui/src/app/form/component/widgets/RadioWidget.js
index 2ce07349d..ddd248bf4 100644
--- a/ui/src/app/form/component/widgets/RadioWidget.js
+++ b/ui/src/app/form/component/widgets/RadioWidget.js
@@ -46,7 +46,7 @@ const RadioWidget = ({
const itemDisabled =
Array.isArray(enumDisabled) &&
enumDisabled.indexOf(option.value) !== -1;
- const checked = option.value.toString() === value.toString();
+ const checked = option?.value?.toString() === value?.toString();
const radio = (
} />
-
+
+
+ } />
+
} />
diff --git a/ui/src/app/metadata/component/properties/PrimitiveProperty.js b/ui/src/app/metadata/component/properties/PrimitiveProperty.js
index f86a798b7..96440749f 100644
--- a/ui/src/app/metadata/component/properties/PrimitiveProperty.js
+++ b/ui/src/app/metadata/component/properties/PrimitiveProperty.js
@@ -9,6 +9,10 @@ export function PrimitiveProperty ({ property, columns }) {
const width = usePropertyWidth(columns);
+ const getValue = (v) => {
+ return property.enum && property.enumNames ? property.enumNames[property.enum.indexOf(v)] : v;
+ }
+
return (
{property.differences &&
Changed: }
@@ -21,7 +25,7 @@ export function PrimitiveProperty ({ property, columns }) {
{ property.name }
{property.value.map((v, valIdx) =>
-
+
) }
diff --git a/ui/src/app/metadata/component/properties/PropertyValue.js b/ui/src/app/metadata/component/properties/PropertyValue.js
index 807c86e61..0476fdb01 100644
--- a/ui/src/app/metadata/component/properties/PropertyValue.js
+++ b/ui/src/app/metadata/component/properties/PropertyValue.js
@@ -3,6 +3,7 @@ import Popover from 'react-bootstrap/Popover';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
import { usePropertyWidth } from './hooks';
+import Translate from '../../../i18n/components/translate';
export function PropertyValue ({ name, value, columns, className }) {
@@ -20,7 +21,9 @@ export function PropertyValue ({ name, value, columns, className }) {
className={`d-block text-truncate ${className}`}
role="definition"
style={columns ? { width } : {}}>
- {value !== undefined ? value.toString() : (value === false) ? value.toString() : '-'}
+
+ {value !== undefined ? value.toString() : (value === false) ? value.toString() : '-'}
+
: - }
diff --git a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js
index 6cdc69b74..e4779199b 100644
--- a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js
+++ b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js
@@ -77,13 +77,6 @@ export const CustomAttributeDefinition = {
}
}
- if (attributeType === 'STRING') {
- parsed = {
- ...parsed,
- defaultValue: data.defaultValueString
- }
- }
-
return parsed;
},
@@ -112,13 +105,6 @@ export const CustomAttributeDefinition = {
}
}
- if (attributeType === 'STRING') {
- formatted = {
- ...formatted,
- defaultValueString: formatted.defaultValue
- }
- }
-
return formatted;
}
}
diff --git a/ui/src/app/metadata/domain/filter/EntityAttributesFilterDefinition.js b/ui/src/app/metadata/domain/filter/EntityAttributesFilterDefinition.js
index 727df9f8f..036557706 100644
--- a/ui/src/app/metadata/domain/filter/EntityAttributesFilterDefinition.js
+++ b/ui/src/app/metadata/domain/filter/EntityAttributesFilterDefinition.js
@@ -53,6 +53,13 @@ export const EntityAttributesFilterWizard = {
errors.entityAttributesFilterTarget.value.addError('message.invalid-regex-pattern');
}
}
+
+ if (formData?.entityAttributesFilterTarget?.entityAttributesFilterTargetType === 'CONDITION_SCRIPT') {
+ const { entityAttributesFilterTarget: { value } } = formData;
+ if (!value[0]) {
+ errors.entityAttributesFilterTarget.value.addError('message.required-for-scripts');
+ }
+ }
return errors;
}
},
diff --git a/ui/src/app/metadata/domain/filter/NameIdFilterDefinition.js b/ui/src/app/metadata/domain/filter/NameIdFilterDefinition.js
index ff16383e9..f092b5813 100644
--- a/ui/src/app/metadata/domain/filter/NameIdFilterDefinition.js
+++ b/ui/src/app/metadata/domain/filter/NameIdFilterDefinition.js
@@ -41,6 +41,13 @@ export const NameIDFilterWizard = {
errors.nameIdFormatFilterTarget.value.addError('message.invalid-regex-pattern');
}
}
+
+ if (formData?.nameIdFormatFilterTarget?.nameIdFormatFilterTargetType === 'CONDITION_SCRIPT') {
+ const { nameIdFormatFilterTarget: { value } } = formData;
+ if (!value[0]) {
+ errors.nameIdFormatFilterTarget.value.addError('message.required-for-scripts');
+ }
+ }
return errors;
}
},
diff --git a/ui/src/app/metadata/editor/MetadataEditor.js b/ui/src/app/metadata/editor/MetadataEditor.js
index c38766404..31bc30da0 100644
--- a/ui/src/app/metadata/editor/MetadataEditor.js
+++ b/ui/src/app/metadata/editor/MetadataEditor.js
@@ -18,6 +18,7 @@ import API_BASE_PATH from '../../App.constant';
import { MetadataObjectContext } from '../hoc/MetadataSelector';
import { FilterableProviders } from '../domain/provider';
import { checkChanges } from '../hooks/utility';
+import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications';
export function MetadataEditor ({ current }) {
@@ -27,6 +28,8 @@ export function MetadataEditor ({ current }) {
const { update, loading } = useMetadataUpdater(`${ API_BASE_PATH }${getMetadataPath(type)}`, current);
+ const notificationDispatch = useNotificationDispatcher();
+
const { data } = useMetadataEntities(type, {}, []);
const history = useHistory();
const definition = React.useContext(MetadataDefinitionContext);
@@ -47,7 +50,8 @@ export function MetadataEditor ({ current }) {
gotoDetail({ refresh: true });
})
.catch(err => {
- window.location.reload();
+ // window.location.reload();
+ notificationDispatch(createNotificationAction(`${err.errorCode} - ${translator(err.errorMessage)}`, NotificationTypes.ERROR))
});
};
diff --git a/ui/src/app/metadata/hoc/MetadataVersionLoader.js b/ui/src/app/metadata/hoc/MetadataVersionLoader.js
index b14e0f59a..e1d17747d 100644
--- a/ui/src/app/metadata/hoc/MetadataVersionLoader.js
+++ b/ui/src/app/metadata/hoc/MetadataVersionLoader.js
@@ -12,9 +12,7 @@ export function MetadataVersionLoader({children}) {
const [metadata, setMetadata] = React.useState();
- const { get, response } = useMetadataEntity(type, {
- cachePolicy: 'no-cache',
- }, []);
+ const { get, response, loading } = useMetadataEntity(type, {}, []);
async function loadVersion(v) {
const l = await get(`/${id}/Versions/${v}`);
@@ -29,10 +27,6 @@ export function MetadataVersionLoader({children}) {
}, [versionId]);
return (
- <>
- {metadata &&
- {children(metadata)}
- }
- >
+ {children(metadata, loading)}
);
}
diff --git a/ui/src/app/metadata/hooks/api.js b/ui/src/app/metadata/hooks/api.js
index d951b66a4..ab835e38e 100644
--- a/ui/src/app/metadata/hooks/api.js
+++ b/ui/src/app/metadata/hooks/api.js
@@ -24,7 +24,9 @@ export function getMetadataPath(type) {
}
export function useNonAdminSources() {
- return useFetch(`/${getMetadataPath('source')}/disabledNonAdmin`);
+ return useFetch(`${API_BASE_PATH}${getMetadataPath('source')}/disabledNonAdmin`, {
+ cachePolicy: 'no-cache'
+ });
}
export function getMetadataListPath(type) {
@@ -109,7 +111,11 @@ export function useMetadataUpdater (path, current) {
}));
});
}
- return Promise.resolve(req);
+ if (response.ok) {
+ return Promise.resolve(req);
+ } else {
+ return Promise.reject(req);
+ }
}
return {
diff --git a/ui/src/app/metadata/new/NewFilter.js b/ui/src/app/metadata/new/NewFilter.js
index 5fce5d31f..4aacb1574 100644
--- a/ui/src/app/metadata/new/NewFilter.js
+++ b/ui/src/app/metadata/new/NewFilter.js
@@ -9,12 +9,14 @@ import { MetadataForm } from '../hoc/MetadataFormContext';
import { MetadataSchema } from '../hoc/MetadataSchema';
import { useMetadataFilters, useMetadataFilterTypes } from '../hooks/api';
import { MetadataFilterTypeSelector } from '../wizard/MetadataFilterTypeSelector';
+import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications';
export function NewFilter() {
const { id, section } = useParams();
const history = useHistory();
const types = useMetadataFilterTypes();
+ const dispatch = useNotificationDispatcher();
const { post, response, loading } = useMetadataFilters(id, {});
@@ -22,9 +24,12 @@ export function NewFilter() {
async function save(metadata) {
- await post(``, metadata);
+ const resp = await post(``, metadata);
if (response.ok) {
+ dispatch(createNotificationAction('Filter saved'));
gotoDetail({ refresh: true });
+ } else {
+ dispatch(createNotificationAction(resp.cause, NotificationTypes.DANGER));
}
};
diff --git a/ui/src/app/metadata/view/EditFilter.js b/ui/src/app/metadata/view/EditFilter.js
index bae6fa78e..5ac69fb8c 100644
--- a/ui/src/app/metadata/view/EditFilter.js
+++ b/ui/src/app/metadata/view/EditFilter.js
@@ -11,9 +11,12 @@ import { MetadataSchema } from '../hoc/MetadataSchema';
import { getMetadataPath, useMetadataUpdater } from '../hooks/api';
import { useMetadataFilterObject } from '../hoc/MetadataFilterSelector';
import API_BASE_PATH from '../../App.constant';
+import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications';
export function EditFilter() {
+ const dispatch = useNotificationDispatcher();
+
const { id, filterId } = useParams();
const filter = useMetadataFilterObject();
const history = useHistory();
@@ -33,10 +36,11 @@ export function EditFilter() {
function save(metadata) {
setBlocking(false);
- update(``, metadata).then(() => {
+ update(``, metadata).then((resp) => {
+ dispatch(createNotificationAction('Filter saved'));
gotoDetail({ refresh: true });
- }).catch(() => {
- window.location.reload();
+ }).catch((error) => {
+ dispatch(createNotificationAction(error.cause, NotificationTypes.DANGER));
});
};
diff --git a/ui/src/app/metadata/view/MetadataConfirmRestore.js b/ui/src/app/metadata/view/MetadataConfirmRestore.js
new file mode 100644
index 000000000..abf791fbb
--- /dev/null
+++ b/ui/src/app/metadata/view/MetadataConfirmRestore.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { MetadataVersionLoader } from '../hoc/MetadataVersionLoader';
+import { Translate } from '../../i18n/components/translate';
+import { useDateFormatter } from '../../core/components/FormattedDate';
+import { faSpinner } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+export function MetadataConfirmRestore () {
+
+ const formatter = useDateFormatter();
+
+ return (
+
+ {(metadata, loading) =>
+
+
+
+
+
+
+ Dashboard
+
+
+
+ {metadata && (metadata.name || metadata.serviceProviderName)}
+
+
+
+
+ <>{loading ?
+
+
+ Loading...
+
+ :
+ <>{metadata &&
+ <>
+
+
+ Restore Version ( date )
+
+
+
+
+
+
+ Create New Version from Previous Settings
+
+
+ Restoring this version will copy the Version ( date ) configuration and create a new Version from the selected version settings. You can then edit the configuration before saving the new version.
+
+
Cancel
+
Restore
+
+
+
+ >
+ }>
+ }
+ >
+
+
+
+
+
+ }
+
+ )
+}
\ No newline at end of file
diff --git a/ui/src/app/metadata/view/MetadataRestore.js b/ui/src/app/metadata/view/MetadataRestore.js
index 9511c4c92..3dd257d4d 100644
--- a/ui/src/app/metadata/view/MetadataRestore.js
+++ b/ui/src/app/metadata/view/MetadataRestore.js
@@ -10,7 +10,8 @@ export function MetadataRestore() {
return (
- {(metadata) =>
+ {(metadata, loading) => <>
+ {metadata &&
- }
+ }
+ >}
);
}
diff --git a/ui/src/app/metadata/view/MetadataUpload.js b/ui/src/app/metadata/view/MetadataUpload.js
index d00be91fe..76ab28c5a 100644
--- a/ui/src/app/metadata/view/MetadataUpload.js
+++ b/ui/src/app/metadata/view/MetadataUpload.js
@@ -22,8 +22,6 @@ export function MetadataUpload() {
async function save({serviceProviderName, file, url}) {
- console.log(serviceProviderName, file);
-
setSaving(true);
const f = file?.length > 0 ? file[0] : null;
diff --git a/ui/src/app/metadata/view/MetadataVersion.js b/ui/src/app/metadata/view/MetadataVersion.js
index 3bde185fa..16fda5c3e 100644
--- a/ui/src/app/metadata/view/MetadataVersion.js
+++ b/ui/src/app/metadata/view/MetadataVersion.js
@@ -5,7 +5,7 @@ import { Configuration } from '../hoc/Configuration';
import { MetadataConfiguration } from '../component/MetadataConfiguration';
import { Link, useParams } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faArrowUp, faHistory, faPlus } from '@fortawesome/free-solid-svg-icons';
+import { faArrowUp, faHistory, faPlus, faSpinner } from '@fortawesome/free-solid-svg-icons';
import { scroller } from 'react-scroll';
@@ -35,7 +35,13 @@ export function MetadataVersion() {
return (
- {(metadata) =>
+ {(metadata, loading) =>
+ <>
+ {loading &&
+
+ Loading...
+
}
+ {metadata &&
{(config) =>
<>
@@ -87,6 +93,7 @@ export function MetadataVersion() {
>
}
+ }>
}
);
diff --git a/ui/src/theme/project/forms.scss b/ui/src/theme/project/forms.scss
index b200b8191..8532aab7d 100644
--- a/ui/src/theme/project/forms.scss
+++ b/ui/src/theme/project/forms.scss
@@ -74,16 +74,21 @@ select.form-control:disabled {
@include component-validation-state("invalid", $form-feedback-invalid-color);
}
+.editor {
+ tab-size: 4ch;
+ max-height: 400px;
+ overflow: auto;
+}
+
.codearea {
- white-space: pre-wrap;
- resize: vertical;
- font-family: monospace;
+ // white-space: pre-wrap;
+ // resize: vertical;
min-height: 166px;
margin-bottom: 0px;
word-break: break-word;
- &[contenteditable] {
- overflow-x: hidden;
- overflow-y: scroll;
+
+ &.is-invalid > pre, &.is-invalid > textarea {
+ outline-color: transparent;
}
}
@@ -123,3 +128,4 @@ mark {
border-left: 0px;
}
}
+