Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Adding a dialog to go to plugin store after an organization is created by the admin #951

Merged
merged 23 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
9 changes: 8 additions & 1 deletion public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@
"cancel": "Cancel",
"noOrgErrorTitle": "Organizations Not Found",
"noOrgErrorDescription": "Please create an organization through dashboard",

"manageFeatures": "Manage Features",
"manageFeaturesInfo": "Creation Successful ! Please select features that you want to enale for this organization from the plugin store.",
"goToStore": "Go to Plugin Store",
"enableEverything": "Enable Everything",
"noResultsFoundFor": "No results found for "
},
"orgListCard": {
Expand Down Expand Up @@ -442,7 +447,9 @@
"addOnEntry": {
"enable": "Enabled",
"install": "Install",
"uninstall": "Uninstall"
"uninstall": "Uninstall",
"uninstallMsg": "This feature is now removed from your organization",
"installMsg": "This feature is now enabled in your organization"
},
"memberDetail": {
"title": "User Details",
Expand Down
4 changes: 2 additions & 2 deletions src/GraphQl/Mutations/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ export const REJECT_ADMIN_MUTATION = gql`
* @description used to toggle `installStatus` (boolean value) of a Plugin
*/
export const UPDATE_INSTALL_STATUS_PLUGIN_MUTATION = gql`
mutation update_install_status_plugin_mutation($id: ID!, $orgId: ID!) {
updatePluginStatus(orgId: $orgId, id: $id) {
mutation ($id: ID!, $orgId: ID!) {
updatePluginStatus(id: $id, orgId: $orgId) {
_id
pluginName
pluginCreatedBy
Expand Down
1 change: 1 addition & 0 deletions src/GraphQl/Queries/Queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ export const PLUGIN_GET = gql`
pluginName
pluginCreatedBy
pluginDesc
uninstalledOrgs
}
}
`;
39 changes: 37 additions & 2 deletions src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const httpLink = new HttpLink({
authorization: 'Bearer ' + localStorage.getItem('token') || '',
},
});

console.error = jest.fn();
const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
cache: new InMemoryCache(),
link: ApolloLink.from([httpLink]),
Expand Down Expand Up @@ -52,12 +52,47 @@ describe('Testing AddOnEntry', () => {
<Provider store={store}>
<BrowserRouter>
<I18nextProvider i18n={i18nForTest}>
{<AddOnEntry {...props} />}
{<AddOnEntry uninstalledOrgs={[]} {...props} />}
</I18nextProvider>
</BrowserRouter>
</Provider>
</ApolloProvider>
);
expect(getByTestId('AddOnEntry')).toBeInTheDocument();
});

it('renders correctly', () => {
const props = {
id: '1',
title: 'Test Addon',
description: 'Test addon description',
createdBy: 'Test User',
component: 'string',
installed: true,
configurable: true,
modified: true,
isInstalled: true,
uninstalledOrgs: [],
enabled: true,
getInstalledPlugins: (): { sample: string } => {
return { sample: 'sample' };
},
};

const { getByText } = render(
<ApolloProvider client={client}>
<Provider store={store}>
<BrowserRouter>
<I18nextProvider i18n={i18nForTest}>
{<AddOnEntry {...props} />}
</I18nextProvider>
</BrowserRouter>
</Provider>
</ApolloProvider>
);

expect(getByText('Test Addon')).toBeInTheDocument();
expect(getByText('Test addon description')).toBeInTheDocument();
expect(getByText('Test User')).toBeInTheDocument();
});
});
134 changes: 27 additions & 107 deletions src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import styles from './AddOnEntry.module.css';
import { Button, Card, Form, Spinner } from 'react-bootstrap';
import {
UPDATE_INSTALL_STATUS_PLUGIN_MUTATION,
UPDATE_ORG_STATUS_PLUGIN_MUTATION,
} from 'GraphQl/Mutations/mutations';
import { Button, Card, Spinner } from 'react-bootstrap';
import { UPDATE_INSTALL_STATUS_PLUGIN_MUTATION } from 'GraphQl/Mutations/mutations';
import { useMutation } from '@apollo/client';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';

interface InterfaceAddOnEntryProps {
id: string;
Expand All @@ -16,131 +14,52 @@
description: string;
createdBy: string;
component: string;
installed?: boolean;
configurable?: boolean;
modified: any;
isInstalled: boolean;
uninstalledOrgs: string[];
getInstalledPlugins: () => any;
}

function addOnEntry({
id,
enabled,
title,
description,
createdBy,
installed,
isInstalled,
uninstalledOrgs,
getInstalledPlugins,
}: InterfaceAddOnEntryProps): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'addOnEntry' });

//getting orgId from URL
const currentOrg = window.location.href.split('/id=')[1] + '';
const [buttonLoading, setButtonLoading] = useState(false);
const [switchInProgress] = useState(false);
const [isInstalledLocal, setIsInstalledLocal] = useState(isInstalled);

const [updateInstallStatus] = useMutation(
const [isInstalledLocal, setIsInstalledLocal] = useState(
uninstalledOrgs.includes(currentOrg)
);
// const [addOrgAsUninstalled] = useMutation(UPDATE_ORG_STATUS_PLUGIN_MUTATION);
const [addOrgAsUninstalled] = useMutation(
UPDATE_INSTALL_STATUS_PLUGIN_MUTATION
);
const [updateOrgStatus] = useMutation(UPDATE_ORG_STATUS_PLUGIN_MUTATION);

const currentOrg = window.location.href.split('=')[1];

const updateOrgList = async (): Promise<void> => {
await updateOrgStatus({
variables: {
id: id.toString(),
orgId: currentOrg.toString(),
},
});
};

const updateInstallStatusFunc = async (): Promise<void> => {
const togglePluginInstall = async (): Promise<void> => {
setButtonLoading(true);
await updateInstallStatus({
await addOrgAsUninstalled({

Check warning on line 44 in src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx#L44

Added line #L44 was not covered by tests
variables: {
id: id.toString(),
status: !isInstalledLocal,
orgId: currentOrg.toString(),
},
});

setIsInstalledLocal(!isInstalledLocal);
setButtonLoading(false);
const dialog: string = isInstalledLocal
? t('installMsg')
: t('uninstallMsg');
toast.success(dialog);

Check warning on line 56 in src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx#L54-L56

Added lines #L54 - L56 were not covered by tests
};

// useEffect(() => {
// // updateInstallStatusFunc();
// }, []);
// TODO: Install/Remove Effect
// 1. Update Server to add to Org
// 2. Validate Permissions
// 3. Trigger Server Hook if Validated. (Stream to track progress)
// const install = () => {
// setButtonLoading(true);
// fetch('http://localhost:3005/installed', {
// method: 'POST',
// headers: {
// 'Content-type': 'application/json; charset=UTF-8',
// },
// body: JSON.stringify(
// Object.assign(
// {},
// { ...entry },
// {
// installedDatetime: new Date(),
// installedBy: 'Admin',
// enabled: true,
// }
// )
// ),
// })
// .then(() => {
// setButtonLoading(false);
// modified();
// })
// .finally(() => setButtonLoading(false));
// };

// const remove = () => {
// setButtonLoading(true);
// fetch(`http://localhost:3005/installed/${id}`, {
// method: 'DELETE',
// })
// .then(() => {
// setButtonLoading(false);
// modified();
// })
// .finally(() => setButtonLoading(false));
// };

// const toggleActive = () => {
// setSwitchState(true);
// fetch(`http://localhost:3005/installed/${id}`, {
// method: 'PUT',
// headers: {
// 'Content-type': 'application/json; charset=UTF-8',
// },
// body: JSON.stringify(
// Object.assign(
// {},
// { ...entry },
// {
// enabled: !enabled,
// }
// )
// ),
// })
// .then(() => {
// modified();
// setSwitchState(false);
// })
// .finally(() => setSwitchState(false));
// };

return (
<>
<Card data-testid="AddOnEntry">
{installed && (
{/* {uninstalledOrgs.includes(currentOrg) && (
<Form.Check
type="switch"
id="custom-switch"
Expand All @@ -151,7 +70,7 @@
disabled={switchInProgress}
checked={enabled}
/>
)}
)} */}
<Card.Body>
<Card.Title>{title}</Card.Title>
<Card.Subtitle className="mb-2 text-muted author">
Expand All @@ -163,22 +82,23 @@
variant="primary"
// disabled={buttonLoading || !configurable}
disabled={buttonLoading}
data-testid="AddOnEntry_btn_install"
onClick={(): void => {
updateOrgList();
updateInstallStatusFunc();
togglePluginInstall();

Check warning on line 87 in src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx#L87

Added line #L87 was not covered by tests
getInstalledPlugins();
// installed ? remove() : install();
}}
>
{buttonLoading ? (
<Spinner animation="grow" />
) : (
<i
className={isInstalledLocal ? 'fa fa-trash' : 'fa fa-cubes'}
className={!isInstalledLocal ? 'fa fa-trash' : 'fa fa-cubes'}
></i>
)}
{/* {installed ? 'Remove' : configurable ? 'Installed' : 'Install'} */}
{isInstalledLocal ? t('uninstall') : t('install')}
{uninstalledOrgs.includes(currentOrg)
? t('install')

Check warning on line 100 in src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx#L100

Added line #L100 was not covered by tests
: t('uninstall')}
</Button>
</Card.Body>
</Card>
Expand Down
Loading