diff --git a/client/admin/apps/AppMenu.js b/client/admin/apps/AppMenu.js
index c0030011bfc5..a7cb1fbe3cc4 100644
--- a/client/admin/apps/AppMenu.js
+++ b/client/admin/apps/AppMenu.js
@@ -174,7 +174,7 @@ function AppMenu({ app, ...props }) {
handleUninstall,
]);
- return
;
+ return ;
}
export default AppMenu;
diff --git a/client/admin/apps/AppProvider.tsx b/client/admin/apps/AppProvider.tsx
index 5c4b6b76d4e6..2cb3ab67eaf9 100644
--- a/client/admin/apps/AppProvider.tsx
+++ b/client/admin/apps/AppProvider.tsx
@@ -24,11 +24,13 @@ type App = {
export type AppDataContextValue = {
data: App[];
dataCache: any;
+ finishedLoading: boolean;
}
export const AppDataContext = createContext({
data: [],
dataCache: [],
+ finishedLoading: false,
});
type ListenersMapping = {
@@ -51,6 +53,7 @@ const registerListeners = (listeners: ListenersMapping): (() => void) => {
const AppProvider: FunctionComponent = ({ children }) => {
const [data, setData] = useState(() => []);
+ const [finishedLoading, setFinishedLoading] = useState(() => false);
const [dataCache, setDataCache] = useState(() => []);
const ref = useRef(data);
@@ -63,12 +66,17 @@ const AppProvider: FunctionComponent = ({ children }) => {
const getDataCopy = (): typeof ref.current => ref.current.slice(0);
useEffect(() => {
+ const updateData = (data: App[]): void => {
+ setData(data.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)));
+ invalidateData();
+ };
+
const handleAppAddedOrUpdated = async (appId: string): Promise => {
try {
const { status, version } = await Apps.getApp(appId);
const app = await Apps.getAppFromMarketplace(appId, version);
const updatedData = getDataCopy();
- const index = updatedData.findIndex(({ id }) => id === appId);
+ const index = updatedData.findIndex(({ id }: {id: string}) => id === appId);
updatedData[index] = {
...app,
installed: true,
@@ -88,7 +96,7 @@ const AppProvider: FunctionComponent = ({ children }) => {
APP_UPDATED: handleAppAddedOrUpdated,
APP_REMOVED: (appId: string): void => {
const updatedData = getDataCopy();
- const index = updatedData.findIndex(({ id }) => id === appId);
+ const index = updatedData.findIndex(({ id }: {id: string}) => id === appId);
if (!updatedData[index]) {
return;
}
@@ -106,7 +114,7 @@ const AppProvider: FunctionComponent = ({ children }) => {
},
APP_STATUS_CHANGE: ({ appId, status }: {appId: string; status: unknown}): void => {
const updatedData = getDataCopy();
- const app = updatedData.find(({ id }) => id === appId);
+ const app = updatedData.find(({ id }: {id: string}) => id === appId);
if (!app) {
return;
@@ -124,11 +132,18 @@ const AppProvider: FunctionComponent = ({ children }) => {
(async (): Promise => {
try {
- const [marketplaceApps, installedApps] = await Promise.all([
- Apps.getAppsFromMarketplace() as Promise,
- Apps.getApps() as Promise,
- ]);
- const appsData = marketplaceApps.map((app) => {
+ const installedApps = await Apps.getApps().then((result) => {
+ let apps: App[] = [];
+ if (result.length) {
+ apps = result.map((current: App) => ({ ...current, installed: true, marketplace: false }));
+ updateData(apps);
+ }
+ return apps;
+ }) as App[];
+
+ const marketplaceApps = await Apps.getAppsFromMarketplace() as App[];
+
+ const appsData = marketplaceApps.length ? marketplaceApps.map((app) => {
const appIndex = installedApps.findIndex(({ id }) => id === app.id);
if (!installedApps[appIndex]) {
return {
@@ -148,14 +163,14 @@ const AppProvider: FunctionComponent = ({ children }) => {
bundledIn: app.bundledIn,
marketplaceVersion: app.version,
};
- });
+ }) : [];
if (installedApps.length) {
- appsData.push(...installedApps.map((current) => ({ ...current, installed: true, marketplace: false })));
+ appsData.push(...installedApps);
}
- setData(appsData.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)));
- invalidateData();
+ updateData(appsData);
+ setFinishedLoading(true);
} catch (e) {
handleAPIError(e);
unregisterListeners();
@@ -163,9 +178,9 @@ const AppProvider: FunctionComponent = ({ children }) => {
})();
return unregisterListeners;
- }, []);
+ }, [setData, setFinishedLoading]);
- return ;
+ return ;
};
export default AppProvider;
diff --git a/client/admin/apps/MarketplaceTable.js b/client/admin/apps/MarketplaceTable.js
index b6d20c43f679..8e7f6a6936eb 100644
--- a/client/admin/apps/MarketplaceTable.js
+++ b/client/admin/apps/MarketplaceTable.js
@@ -124,7 +124,7 @@ function MarketplaceTable() {
const [sort, setSort] = useState(['name', 'asc']);
const { text, current, itemsPerPage } = params;
- const { data, dataCache } = useContext(AppDataContext);
+ const { data, dataCache, finishedLoading } = useContext(AppDataContext);
const [filteredApps, filteredAppsCount] = useFilteredApps({
filterFunction: useCallback(
(text) => ({ name, marketplace }) => marketplace !== false && name.toLowerCase().indexOf(text.toLowerCase()) > -1,
@@ -174,7 +174,7 @@ function MarketplaceTable() {
{t('Status')}
>}
- results={filteredApps}
+ results={(filteredApps?.length || finishedLoading) && filteredApps}
total={filteredAppsCount}
setParams={setParams}
params={params}
diff --git a/client/admin/users/UserInfoActions.js b/client/admin/users/UserInfoActions.js
index 2f210645da4c..c02fc692c611 100644
--- a/client/admin/users/UserInfoActions.js
+++ b/client/admin/users/UserInfoActions.js
@@ -256,7 +256,7 @@ export const UserInfoActions = ({ username, _id, isActive, isAdmin, onChange, ..
{ actions && actions.map((action, index) => ())}
- { moreActions && }
+ { moreActions && }
{ modal }
diff --git a/client/fuselage-hooks.d.ts b/client/fuselage-hooks.d.ts
deleted file mode 100644
index 2bef8fec95ab..000000000000
--- a/client/fuselage-hooks.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-declare module '@rocket.chat/fuselage-hooks' {
- export const useDebouncedCallback: (fn: (...args: any[]) => any, ms: number, deps: any[]) => (...args: any[]) => any;
- export const useMutableCallback: (fn: (...args: any[]) => any) => (...args: any[]) => any;
-}
diff --git a/package-lock.json b/package-lock.json
index 4e2a525f86f3..1c8ef9a9592d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2728,9 +2728,9 @@
}
},
"@rocket.chat/css-in-js": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/css-in-js/-/css-in-js-0.10.0.tgz",
- "integrity": "sha512-Zo/18kmiRtuGGzFtCYJz1DGs1+j6MBTKWM/n6+bmgw3ubCuSsG1t12KtJl87BBwVnJwC7W+oxqesM8llUF5Odw==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/css-in-js/-/css-in-js-0.13.0.tgz",
+ "integrity": "sha512-WnwjR1Ye7bGuj2YOaaros9IqDRpLFC8mBShoQ5vpV5MvBaNHDUu9l94pAoeSqkl5r7LMkLiVCFbMVUBivWaTqQ==",
"requires": {
"@emotion/hash": "^0.8.0",
"@emotion/stylis": "^0.8.5"
@@ -2746,25 +2746,36 @@
}
},
"@rocket.chat/fuselage": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage/-/fuselage-0.10.0.tgz",
- "integrity": "sha512-P2LO5g6pQvUfE1Or1AjgFZWV45v+6htGejwRovPtZRbRAngHT9dJcTfDfykjncCEptZi6xBvEh+pkCgcZ1fCng==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage/-/fuselage-0.13.0.tgz",
+ "integrity": "sha512-FB3usvEBHuoJYwEW/tCRNRjKxiiWEwx3SKrn11FsVCEuUluk7a4HtaY73TOSVd1/3nv3AzMYFG1DZde1TGixTA==",
"requires": {
- "@rocket.chat/css-in-js": "^0.10.0",
- "@rocket.chat/fuselage-tokens": "^0.10.0",
+ "@rocket.chat/css-in-js": "^0.13.0",
+ "@rocket.chat/fuselage-tokens": "^0.13.0",
"invariant": "^2.2.4",
"react-keyed-flatten-children": "^1.2.0"
}
},
"@rocket.chat/fuselage-hooks": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-hooks/-/fuselage-hooks-0.10.0.tgz",
- "integrity": "sha512-oU3MgNakM32yqwXVS7lXnOvYjwNtkOpext1NMsAsirjfvhFz+CwdFEqLgn6uGVohoiR3KvV4xJSN/ZaF5WhRCQ=="
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-hooks/-/fuselage-hooks-0.13.0.tgz",
+ "integrity": "sha512-d+IH+WEwjduGSfuIyAeXCGIyj7xypLNGEMEeNeNbmmCk7FBtK5pz4TCa2Hzx+2hAzQptPJOVWR1oKWMps4d7lA==",
+ "requires": {
+ "@rocket.chat/fuselage-tokens": "^0.13.0",
+ "use-subscription": "^1.4.1"
+ },
+ "dependencies": {
+ "@rocket.chat/fuselage-tokens": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-tokens/-/fuselage-tokens-0.13.0.tgz",
+ "integrity": "sha512-C0BCyt+k0ZPU31LZNPoxnIaH08OCNNJa8nHoky7SR95Tq/Y9U6I42Yh11q9lc05KhoOGcVkenm4k+v8eBP5ARw=="
+ }
+ }
},
"@rocket.chat/fuselage-polyfills": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-polyfills/-/fuselage-polyfills-0.10.0.tgz",
- "integrity": "sha512-WmWLWXed4vKySWtvDr9umFBcZ7tk0MWL7gFGsDV0tSuQpBjRGW3gfOBkGnvay0DG+UzJbw9pLUWXAbArBNDCNw==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-polyfills/-/fuselage-polyfills-0.13.0.tgz",
+ "integrity": "sha512-moaIdPj9G4xWKu8bkXJaXiLOHOSkLVXJ+zciOKyD8Vet1D8bFqNdSgRC6nc50CXtW6Imk98bl/as/M228gOAfw==",
"requires": {
"@juggle/resize-observer": "^3.1.2",
"clipboard-polyfill": "^2.8.6",
@@ -2772,22 +2783,22 @@
}
},
"@rocket.chat/fuselage-tokens": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-tokens/-/fuselage-tokens-0.10.0.tgz",
- "integrity": "sha512-q7LHbeGHqOt+6g05FNAPkR8hEknxHrhvIp4K4DlLWaPrLCySdPp1lmXZuSO+AoGl69Y/e8BdWmK46K2PAhzwGw=="
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-tokens/-/fuselage-tokens-0.13.0.tgz",
+ "integrity": "sha512-C0BCyt+k0ZPU31LZNPoxnIaH08OCNNJa8nHoky7SR95Tq/Y9U6I42Yh11q9lc05KhoOGcVkenm4k+v8eBP5ARw=="
},
"@rocket.chat/fuselage-ui-kit": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-ui-kit/-/fuselage-ui-kit-0.10.0.tgz",
- "integrity": "sha512-2wrJjcKUN0fOPUhllMA/+nJkJLlz7GZ5NI+eG2snUjuaEyi8LUWGqdd7Xqx4hZOxm4wG24hFJaxc4WQb4kCO2Q==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-ui-kit/-/fuselage-ui-kit-0.13.0.tgz",
+ "integrity": "sha512-mXWJMuQ3HU8Jfq28MUS9flLOi0yBBndF3ZZg8MszLJA9xI8r8hls6edGP1S0Hd6GzKDxI3pEIrJSRQbpAX9+ug==",
"requires": {
- "@rocket.chat/ui-kit": "^0.10.0"
+ "@rocket.chat/ui-kit": "^0.13.0"
}
},
"@rocket.chat/icons": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/icons/-/icons-0.10.0.tgz",
- "integrity": "sha512-gtXIIQf8pCLVLcUtd7cbt/OukM9XlnmK9+du4utc5LIvuNHJaaekSFv9Bg3URy41P/8Ss9dc6FmDnlPna4F19g=="
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/icons/-/icons-0.13.0.tgz",
+ "integrity": "sha512-gZ9ydWhmSLU29PmRX5p3mFS5wwAKYf/dwUaqyoPWXAwehiZGAj5SDFcWDKeqkh5FH9D8lCRMHVNBLBVZI5xrKw=="
},
"@rocket.chat/livechat": {
"version": "1.6.0",
@@ -2896,9 +2907,9 @@
}
},
"@rocket.chat/ui-kit": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rocket.chat/ui-kit/-/ui-kit-0.10.0.tgz",
- "integrity": "sha512-zCMDsxdmUvKD9zzyskiV8kThIcsAaXvZT1LzFk4yLq2Wh5meTJ+TClgt9Zn3pBdO/2mwdjBueiGc+k+vqNIqRg=="
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@rocket.chat/ui-kit/-/ui-kit-0.13.0.tgz",
+ "integrity": "sha512-xY8xc98KGshyOJM2GCLnYE9TTevViO7bVeY1HVRB2anDutgHRFgt6qFW1eiaB8s+6J+5I6VTE3k0jzQeaRsAeg=="
},
"@samverschueren/stream-to-observable": {
"version": "0.3.0",
diff --git a/package.json b/package.json
index 800cc6dbf783..a2da8316fb7c 100644
--- a/package.json
+++ b/package.json
@@ -129,14 +129,13 @@
"@nivo/line": "^0.61.1",
"@nivo/pie": "^0.61.1",
"@rocket.chat/apps-engine": "1.16.0-alpha.3466",
- "@rocket.chat/css-in-js": "^0.10.0",
- "@rocket.chat/fuselage": "^0.10.0",
- "@rocket.chat/fuselage-hooks": "^0.10.0",
- "@rocket.chat/fuselage-polyfills": "^0.10.0",
- "@rocket.chat/fuselage-ui-kit": "^0.10.0",
- "@rocket.chat/icons": "^0.10.0",
- "@rocket.chat/mp3-encoder": "^0.13.0",
- "@rocket.chat/ui-kit": "^0.10.0",
+ "@rocket.chat/css-in-js": "^0.13.0",
+ "@rocket.chat/fuselage": "^0.13.0",
+ "@rocket.chat/fuselage-hooks": "^0.13.0",
+ "@rocket.chat/fuselage-polyfills": "^0.13.0",
+ "@rocket.chat/fuselage-ui-kit": "^0.13.0",
+ "@rocket.chat/icons": "^0.13.0",
+ "@rocket.chat/ui-kit": "^0.13.0",
"@slack/client": "^4.8.0",
"@types/fibers": "^3.1.0",
"@types/underscore.string": "0.0.38",