Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/admin/apps/AppMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function AppMenu({ app, ...props }) {
handleUninstall,
]);

return <Menu options={menuOptions} placement='bottom left' {...props}/>;
return <Menu options={menuOptions} placement='bottom-start' {...props}/>;
}

export default AppMenu;
43 changes: 29 additions & 14 deletions client/admin/apps/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ type App = {
export type AppDataContextValue = {
data: App[];
dataCache: any;
finishedLoading: boolean;
}

export const AppDataContext = createContext<AppDataContextValue>({
data: [],
dataCache: [],
finishedLoading: false,
});

type ListenersMapping = {
Expand All @@ -51,6 +53,7 @@ const registerListeners = (listeners: ListenersMapping): (() => void) => {

const AppProvider: FunctionComponent = ({ children }) => {
const [data, setData] = useState<App[]>(() => []);
const [finishedLoading, setFinishedLoading] = useState<boolean>(() => false);
const [dataCache, setDataCache] = useState<any>(() => []);

const ref = useRef(data);
Expand All @@ -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<void> => {
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,
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -124,11 +132,18 @@ const AppProvider: FunctionComponent = ({ children }) => {

(async (): Promise<void> => {
try {
const [marketplaceApps, installedApps] = await Promise.all([
Apps.getAppsFromMarketplace() as Promise<App[]>,
Apps.getApps() as Promise<App[]>,
]);
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 {
Expand All @@ -148,24 +163,24 @@ 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();
}
})();

return unregisterListeners;
}, []);
}, [setData, setFinishedLoading]);

return <AppDataContext.Provider children={children} value={{ data, dataCache }} />;
return <AppDataContext.Provider children={children} value={{ data, dataCache, finishedLoading }} />;
};

export default AppProvider;
4 changes: 2 additions & 2 deletions client/admin/apps/MarketplaceTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -174,7 +174,7 @@ function MarketplaceTable() {
{t('Status')}
</GenericTable.HeaderCell>
</>}
results={filteredApps}
results={(filteredApps?.length || finishedLoading) && filteredApps}
total={filteredAppsCount}
setParams={setParams}
params={params}
Expand Down
2 changes: 1 addition & 1 deletion client/admin/users/UserInfoActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export const UserInfoActions = ({ username, _id, isActive, isAdmin, onChange, ..
<Box display='flex' flexDirection='row' {...props}>
<ButtonGroup flexGrow={1} justifyContent='center'>
{ actions && actions.map((action, index) => (<Button key={index} onClick={action.action}>{action.label}</Button>))}
{ moreActions && <Menu options={moreActions} placement='bottom left'/> }
{ moreActions && <Menu options={moreActions} placement='bottom-start'/> }
</ButtonGroup>
</Box>
{ modal }
Expand Down
4 changes: 0 additions & 4 deletions client/fuselage-hooks.d.ts

This file was deleted.

65 changes: 38 additions & 27 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +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/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",
Expand Down