Skip to content

Commit

Permalink
Add form & use panel for other api details
Browse files Browse the repository at this point in the history
  • Loading branch information
quentinovega committed Nov 29, 2024
1 parent 5b8f992 commit c0e68ed
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export const ApiHeader = ({
if (!isError(response)) {
queryClient.invalidateQueries({ queryKey: ["api"] });
closeRightPanel();
toast.success("update.api.sucecssful.toast.label");
toast.success("update.api.successful.toast.label");
navigate(`/${ownerTeam._humanReadableId}/${response._humanReadableId}/${response.currentVersion}/description`)
} else {
toast.error(response.error);
Expand Down
5 changes: 3 additions & 2 deletions daikoku/javascript/src/components/frontend/api/ApiHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ export const ApiHome = ({

const saveApi = (api: IApi) => {
return (
Promise.resolve(console.debug({ api }))
.then(() => toast.success('Bravo'))
Promise.resolve(Services.saveTeamApi((ownerTeamQuery.data as ITeamSimple)._id, api, api.currentVersion))
.then(() => toast.success(translate('update.api.successful.toast.label')))
.then(() => queryClient.invalidateQueries({ queryKey: ['api']}))
)
}

Expand Down
51 changes: 37 additions & 14 deletions daikoku/javascript/src/components/frontend/api/ApiRedoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,48 @@ export function ApiRedoc<T extends IWithSwagger>(props: ApiRedocProps<T>) {
message: translate('api_redoc.guest_user')
})
return <></>
} else if (props.swaggerConf?.specificationType === SpecificationType.openapi) {
} else {
const openApiDocForm = () => openRightPanel({
title: translate('update.api.details.panel.title'),
content: <div>
<TeamApiSwagger value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
</div>
})


return <div>
<Can I={manage} a={API} team={props.ownerTeam}>
<More
className="a-fake"
aria-label="update api"
style={{ position: "absolute", right: 0 }}
onClick={() => openRightPanel({
title: "Update api",
content:
<TeamApiSwagger value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
})
} />
aria-label={translate('update.api.openapi.btn.label')}
data-bs-toggle="dropdown"
aria-expanded="false"
id={`${props.entity._id}-dropdownMenuButton`}
style={{ position: "absolute", right: 0 }} />
<div className="dropdown-menu" aria-labelledby={`${props.entity._id}-dropdownMenuButton`}>
<span
onClick={() => openApiDocForm()}
className="dropdown-item cursor-pointer"
>
{translate('update.api.openapi.btn.label')}
</span>
{props.entity.swagger && <div className="dropdown-divider" />}
{props.entity.swagger && <span
onClick={() => props.save({ ...props.entity, swagger: null })}
className="dropdown-item cursor-pointer btn-outline-danger"
>
{translate('update.api.testing.delete.btn.label')}
</span>}
</div>
</Can>
<RedocStandalone specUrl={props.swaggerUrl} options={{ downloadFileName, pathInMiddlePanel: true, sideNavStyle: SideNavStyleEnum.PathOnly, ...(props.swaggerConf?.additionalConf || {}) }} />
{props.swaggerConf?.specificationType === SpecificationType.openapi && <RedocStandalone specUrl={props.swaggerUrl} options={{ downloadFileName, pathInMiddlePanel: true, sideNavStyle: SideNavStyleEnum.PathOnly, ...(props.swaggerConf?.additionalConf || {}) }} />}
{props.swaggerConf?.specificationType === SpecificationType.asyncapi && <AsyncApiComponent schema={spec} config={config} />}
{!props.swaggerConf && (
<div className={`alert alert-info col-6 text-center mx-auto`} role='alert'>
<div>{translate('update.api.openapi.not.found.alert')}</div>
<button className="btn btn-outline-info" onClick={openApiDocForm}>{translate('update.api.openapi.btn.label')}</button>
</div>
)}
</div>
} else if (props.swaggerConf?.specificationType === SpecificationType.asyncapi && spec) {
return <AsyncApiComponent schema={spec} config={config} />
} else {
return <Spinner />
}
}
110 changes: 65 additions & 45 deletions daikoku/javascript/src/components/frontend/api/ApiSwagger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import { toast } from 'sonner';

import { I18nContext, ModalContext } from '../../../contexts';
import { GlobalContext } from '../../../contexts/globalContext';
import { IApi, ISwagger, ITeamSimple, ITesting, IWithSwagger } from '../../../types';
import { IApi, ISwagger, ITeamSimple, ITesting, IWithSwagger, IWithTesting } from '../../../types';
import { Can, manage, api as API } from '../../utils';

import 'swagger-ui-dist/swagger-ui.css';
import { Form, format, type } from '@maif/react-forms';
import { TeamApiSwagger } from '../../backoffice';
import { TeamApiSwagger, TeamApiTesting } from '../../backoffice';


type ApiSwaggerProps<T extends IWithSwagger> = {
type ApiSwaggerProps<T extends IWithTesting> = {
testing?: ITesting,
swagger?: ISwagger,
swaggerUrl: string,
Expand All @@ -26,7 +26,7 @@ type ApiSwaggerProps<T extends IWithSwagger> = {
entity: T
save: (d: T) => Promise<any>
}
export function ApiSwagger<T extends IWithSwagger>(props: ApiSwaggerProps<T>) {
export function ApiSwagger<T extends IWithTesting>(props: ApiSwaggerProps<T>) {

const { tenant, connectedUser } = useContext(GlobalContext)

Expand Down Expand Up @@ -129,45 +129,65 @@ export function ApiSwagger<T extends IWithSwagger>(props: ApiSwaggerProps<T>) {
message: translate('api_swagger.guest_user')
})

// const api = props.api;
if (!props._id) return <div>{translate({ key: 'api_data.missing', replacements: ['Swagger'] })}</div>;

if (state.error || state.info)
return (
<div className="d-flex justify-content-center w-100">
<Can I={manage} a={API} team={props.ownerTeam}>
<More
className="a-fake"
aria-label="update api"
style={{ position: "absolute", right: 0 }}
onClick={() => openRightPanel({
title: "Update api",
content:
<TeamApiSwagger value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
})
} />
</Can>
<span className={`alert alert-${state.error ? 'danger' : 'info'} text-center`}>
{state.error ? state.error : state.info}
</span>
</div>
);
else
return (
<div style={{ width: '100%' }}>
<Can I={manage} a={API} team={props.ownerTeam}>
<More
className="a-fake"
aria-label="update api"
style={{ position: "absolute", right: 0 }}
onClick={() => openRightPanel({
title: "Update api",
content:
<TeamApiSwagger value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
})
} />
</Can>
<div id="swagger-ui" style={{ width: '100%' }} />
</div>
);
const openApiDocForm = () => openRightPanel({
title: translate('update.api.details.panel.title'),
content: <div>
<TeamApiSwagger value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
</div>
})
//FIXME: teamAPiTesting does not work on right panel right now
const openTestingForm = () => openRightPanel({
title: "Update api",
content:
<TeamApiTesting currentTeam={props.ownerTeam} value={props.entity} save={d => props.save(d).then(closeRightPanel)} />
})

return (
<div className="d-flex justify-content-center w-100">
<Can I={manage} a={API} team={props.ownerTeam}>
<More
className="a-fake"
aria-label={translate('update.api.testing.btn.label')}
data-bs-toggle="dropdown"
aria-expanded="false"
id={`${props.entity._id}-dropdownMenuButton`}
style={{ position: "absolute", right: 0 }} />

<div className="dropdown-menu" aria-labelledby={`${props.entity._id}-dropdownMenuButton`}>
{!props.swagger && <span
onClick={() => openApiDocForm()}
className="dropdown-item cursor-pointer"
>
{translate('update.api.openapi.btn.label')}
</span>}
{props.swagger && <span
onClick={openTestingForm}
className="dropdown-item cursor-pointer"
>
{translate('update.api.testing.btn.label')}
</span>}
{props.entity.testing && <div className="dropdown-divider" />}
{props.entity.testing && <span
onClick={() => props.save({...props.entity, testing: null})}
className="dropdown-item cursor-pointer btn-outline-danger"
>
{translate('update.api.testing.delete.btn.label')}
</span>}
</div>
</Can>
{!props.swagger && (
<div className={`alert alert-info col-6 text-center mx-auto`} role='alert'>
<div>{translate('update.api.openapi.not.found.alert')}</div>
<button className="btn btn-outline-info" onClick={openApiDocForm}>{translate('update.api.openapi.btn.label')}</button>
</div>
)}
{props.swagger && !props.testing && (
<div className={`alert alert-info col-6 text-center mx-auto`} role='alert'>
<div>{translate('update.api.testing.not.found.alert')}</div>
<button className="btn btn-outline-info" onClick={openTestingForm}>{translate('update.api.testing.btn.label')}</button>
</div>
)}
{props.swagger && props.testing && <div id="swagger-ui" style={{ width: '100%' }} />}
</div>
);
}
15 changes: 9 additions & 6 deletions daikoku/javascript/src/contexts/navContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,31 +140,34 @@ export const useApiFrontOffice = (api?: IApi, team?: ITeamSimple) => {
swagger: {
label: translate('Swagger'),
action: () => {
if (api?.swagger?.content || api?.swagger?.url) navigateTo('swagger');
if (userCanUpdateApi || api?.swagger?.content || api?.swagger?.url) navigateTo('swagger');
},
className: {
active: currentTab === 'swagger',
disabled: tenant.display === 'environment' || !api?.swagger?.content && !api?.swagger?.url,
disabled: !userCanUpdateApi && (tenant.display === 'environment' || !api?.swagger?.content && !api?.swagger?.url),
'd-none': tenant.display === 'environment'
},
},
testing: {
label: translate('Testing'),
action: () => {
if (api?.testing?.enabled) navigateTo('testing');
if (userCanUpdateApi || api?.testing?.enabled) navigateTo('testing');
},
className: {
active: currentTab === 'testing',
disabled: tenant.display === 'environment' || !api?.testing?.enabled,
disabled: !userCanUpdateApi && (tenant.display === 'environment' || !api?.testing?.enabled),
'd-none': tenant.display === 'environment'
},
},
news: {
label: translate('News'),
action: () => {
if (api?.posts?.length) navigateTo('news');
if (userCanUpdateApi || api?.posts?.length) navigateTo('news');
},
className: {
active: currentTab === 'news',
disabled: !userCanUpdateApi && !api?.posts?.length
},
className: { active: currentTab === 'news', disabled: !api?.posts?.length },
},
issues: {
label: translate('Issues'),
Expand Down
9 changes: 8 additions & 1 deletion daikoku/javascript/src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,12 @@
"update.api.description.successful.toast.label": "Description has been succesfully updated",
"api.form.header.flow.label": "Header",
"api.form.cms.header.label": "Custom API header from CMS page",
"api.form.cms.header.help": "Define a custom API header by using a CMS page."
"api.form.cms.header.help": "Define a custom API header by using a CMS page.",
"update.api.openapi.btn.label": "Edit API documentation",
"update.api.openapi.delete.btn.label": "Delete API documentation",
"update.api.testing.btn.label": "Edit API testing configuration",
"update.api.testing.delete.btn.label": "Delete testing configuration",
"update.api.successful.toast.label": "API succesfully updated",
"update.api.openapi.not.found.alert": "No API documentation configured.",
"update.api.testing.not.found.alert": "No API testing configured."
}
9 changes: 8 additions & 1 deletion daikoku/javascript/src/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,12 @@
"update.api.description.successful.toast.label": "La description a été modifée avec succès.",
"api.form.header.flow.label": "Entête",
"api.form.cms.header.label": "En-tête d'API personnalisé à partir de la page CMS",
"api.form.cms.header.help": "Définissez un en-tête d'API personnalisé à l'aide d'une page CMS."
"api.form.cms.header.help": "Définissez un en-tête d'API personnalisé à l'aide d'une page CMS.",
"update.api.openapi.btn.label": "Editer la documentation d'API",
"update.api.openapi.delete.btn.label": "Supprimer la documentation d'API",
"update.api.testing.btn.label": "Editer la configuration de test de l'API",
"update.api.testing.delete.btn.label": "Supprimer la configuration de test de l'API",
"update.api.successful.toast.label": "API succesfully updated",
"update.api.openapi.not.found.alert": "Aucune documentation d'API configurée.",
"update.api.testing.not.found.alert": "Aucun test d'API configuré."
}
1 change: 1 addition & 0 deletions daikoku/javascript/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface IWithDocumentation {
documentation?: IDocumentation;
}
export interface IWithSwagger {
_id: string;
swagger?: ISwagger;
}

Expand Down

0 comments on commit c0e68ed

Please sign in to comment.