diff --git a/ui/src/app/core/components/Spinner.js b/ui/src/app/core/components/Spinner.js
new file mode 100644
index 000000000..880f53d2a
--- /dev/null
+++ b/ui/src/app/core/components/Spinner.js
@@ -0,0 +1,9 @@
+import React from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faSpinner } from '@fortawesome/free-solid-svg-icons';
+
+export function Spinner ({ size, className }) {
+ return ()
+}
+
+export default Spinner;
\ No newline at end of file
diff --git a/ui/src/app/dashboard/view/ActionsTab.js b/ui/src/app/dashboard/view/ActionsTab.js
index 30bc9e371..eda40b751 100644
--- a/ui/src/app/dashboard/view/ActionsTab.js
+++ b/ui/src/app/dashboard/view/ActionsTab.js
@@ -1,11 +1,12 @@
import React from 'react';
import { MetadataActions } from '../../admin/container/MetadataActions';
import UserActions from '../../admin/container/UserActions';
+import Spinner from '../../core/components/Spinner';
import Translate from '../../i18n/components/translate';
import SourceList from '../../metadata/domain/source/component/SourceList';
-export function ActionsTab({ sources, users, reloadSources, reloadUsers }) {
+export function ActionsTab({ sources, users, reloadSources, reloadUsers, loadingSources, loadingUsers }) {
return (
<>
@@ -21,7 +22,9 @@ export function ActionsTab({ sources, users, reloadSources, reloadUsers }) {
{(enable) =>
- enable(s, e, reloadSources)} />
+ enable(s, e, reloadSources)}>
+ {loadingSources &&
}
+
}
@@ -36,7 +39,9 @@ export function ActionsTab({ sources, users, reloadSources, reloadUsers }) {
-
+
+ {loadingUsers &&
}
+
>
diff --git a/ui/src/app/dashboard/view/AdminTab.js b/ui/src/app/dashboard/view/AdminTab.js
index 5c116c242..ba71e0685 100644
--- a/ui/src/app/dashboard/view/AdminTab.js
+++ b/ui/src/app/dashboard/view/AdminTab.js
@@ -5,12 +5,13 @@ import UserMaintenance from '../../admin/component/UserMaintenance';
import API_BASE_PATH from '../../App.constant';
import Translate from '../../i18n/components/translate';
+import Spinner from '../../core/components/Spinner';
export function AdminTab () {
const [users, setUsers] = React.useState([]);
- const { get, response } = useFetch(`${API_BASE_PATH}/admin/users`, {
+ const { get, response, loading } = useFetch(`${API_BASE_PATH}/admin/users`, {
cachePolicy: 'no-cache'
}, []);
@@ -46,7 +47,9 @@ export function AdminTab () {
onChangeUserRole={onChangeUserRole}
onDeleteUser={onDeleteUser}
onChangeUserGroup={onChangeUserGroup} />}
+
+ {loading &&
}
diff --git a/ui/src/app/dashboard/view/Dashboard.js b/ui/src/app/dashboard/view/Dashboard.js
index e5f145572..49cba4079 100644
--- a/ui/src/app/dashboard/view/Dashboard.js
+++ b/ui/src/app/dashboard/view/Dashboard.js
@@ -26,13 +26,13 @@ export function Dashboard () {
const isAdmin = useIsAdmin();
- const loading = useCurrentUserLoading();
+ const loadingUser = useCurrentUserLoading();
const [actions, setActions] = React.useState(0);
const [users, setUsers] = React.useState([]);
const [sources, setSources] = React.useState([]);
- const { get, response } = useFetch(`${API_BASE_PATH}`, {
+ const { get, response, loading } = useFetch(`${API_BASE_PATH}`, {
cachePolicy: 'no-cache'
});
@@ -64,7 +64,7 @@ export function Dashboard () {
return (
- {loading ?
+ {loadingUser ?
@@ -109,7 +109,13 @@ export function Dashboard () {
} />
-
+
} />
>
diff --git a/ui/src/app/dashboard/view/ProvidersTab.js b/ui/src/app/dashboard/view/ProvidersTab.js
index 023a7f78a..d986f3f68 100644
--- a/ui/src/app/dashboard/view/ProvidersTab.js
+++ b/ui/src/app/dashboard/view/ProvidersTab.js
@@ -8,13 +8,14 @@ import { Ordered } from '../component/Ordered';
import { useIsAdmin } from '../../core/user/UserContext';
import Alert from 'react-bootstrap/Alert';
import { MetadataActions } from '../../admin/container/MetadataActions';
+import Spinner from '../../core/components/Spinner';
const searchProps = ['name', '@type', 'createdBy'];
export function ProvidersTab () {
const [providers, setProviders] = React.useState([]);
- const { get, response } = useMetadataEntities('provider', {
+ const { get, response, loading } = useMetadataEntities('provider', {
cachePolicy: 'no-cache'
});
@@ -54,7 +55,9 @@ export function ProvidersTab () {
last={last}
onEnable={(p, e) => enable(p, e, loadProviders)}
onOrderUp={onOrderUp}
- onOrderDown={onOrderDown}>
+ onOrderDown={onOrderDown}>
+ {loading &&
}
+
}
}
diff --git a/ui/src/app/dashboard/view/SourcesTab.js b/ui/src/app/dashboard/view/SourcesTab.js
index b564a3872..40ff4dd4f 100644
--- a/ui/src/app/dashboard/view/SourcesTab.js
+++ b/ui/src/app/dashboard/view/SourcesTab.js
@@ -5,9 +5,11 @@ import Translate from '../../i18n/components/translate';
import SourceList from '../../metadata/domain/source/component/SourceList';
import { useMetadataEntities, useMetadataEntity } from '../../metadata/hooks/api';
import { Search } from '../component/Search';
+import { Spinner } from '../../core/components/Spinner';
import { NotificationContext, createNotificationAction, NotificationTypes } from '../../notifications/hoc/Notifications';
+
const searchProps = ['serviceProviderName', 'entityId', 'createdBy'];
export function SourcesTab () {
@@ -16,7 +18,7 @@ export function SourcesTab () {
const [sources, setSources] = React.useState([]);
- const { get, response } = useMetadataEntities('source', {
+ const { get, response, loading } = useMetadataEntities('source', {
cachePolicy: 'no-cache'
});
@@ -68,7 +70,9 @@ export function SourcesTab () {
entities={searched}
onDelete={(id) => remove(id, loadSources)}
onEnable={(s, e) => enable(s, e, loadSources) }
- onChangeGroup={changeSourceGroup} />
+ onChangeGroup={changeSourceGroup}>
+ {loading &&
}
+
}
}
diff --git a/ui/src/app/metadata/domain/provider/component/ProviderList.js b/ui/src/app/metadata/domain/provider/component/ProviderList.js
index 3e559eb2a..1b367a69d 100644
--- a/ui/src/app/metadata/domain/provider/component/ProviderList.js
+++ b/ui/src/app/metadata/domain/provider/component/ProviderList.js
@@ -12,7 +12,7 @@ import { Scroller } from '../../../../dashboard/component/Scroller';
import { useIsAdmin } from '../../../../core/user/UserContext';
import { useTranslator } from '../../../../i18n/hooks';
-export function ProviderList({ entities, reorder = true, first, last, onEnable, onOrderUp, onOrderDown }) {
+export function ProviderList({ children, entities, reorder = true, first, last, onEnable, onOrderUp, onOrderDown }) {
const isAdmin = useIsAdmin();
const translator = useTranslator();
@@ -91,6 +91,7 @@ export function ProviderList({ entities, reorder = true, first, last, onEnable,
)}
+ {children}
}
diff --git a/ui/src/app/metadata/domain/source/component/SourceList.js b/ui/src/app/metadata/domain/source/component/SourceList.js
index 109396c2c..42af027dd 100644
--- a/ui/src/app/metadata/domain/source/component/SourceList.js
+++ b/ui/src/app/metadata/domain/source/component/SourceList.js
@@ -16,7 +16,7 @@ import { useTranslator } from '../../../../i18n/hooks';
import { useCanEnable, useIsAdmin } from '../../../../core/user/UserContext';
import { GroupsProvider } from '../../../../admin/hoc/GroupsProvider';
-export default function SourceList({ entities, onDelete, onEnable, onChangeGroup }) {
+export default function SourceList({ entities, onDelete, onEnable, onChangeGroup, children }) {
const translator = useTranslator();
const isAdmin = useIsAdmin();
@@ -122,6 +122,7 @@ export default function SourceList({ entities, onDelete, onEnable, onChangeGroup
+ {children}
}