Skip to content

Commit

Permalink
EP-786 feat(dashboard): allow read and edit of mocked projects (#37)
Browse files Browse the repository at this point in the history
Co-authored-by: Rebecca Dumazert <44778533+rebeccadumazert@users.noreply.github.com>
  • Loading branch information
douglasduteil and rebeccadumazert authored Nov 28, 2023
1 parent 9bf09e4 commit 47c480f
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 64 deletions.
33 changes: 32 additions & 1 deletion back/src/oidc-client/oidc-client.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
Body,
Controller,
Get,
HttpException,
HttpStatus,
Param,
Post,
} from '@nestjs/common';
import { CreateOidcClientDto } from './oidc-client.dto';
Expand All @@ -13,6 +15,35 @@ export class OidcClientController {
constructor(private readonly oidcClientSaver: OidcClientSaver) {
this.oidcClientSaver = oidcClientSaver;
}

@Get()
async findAll() {
return [
{
clientDescription: 'Description',
clientId: 'clientId',
clientSecret: 'ClientSecret',
clientName: 'Rebecca Project 123',
redirectUris: ['http://example.com/callback'],
postLogoutRedirectUris: ['http://example.com/logout'],
scope: ['firstname', 'lastname'],
},
] satisfies CreateOidcClientDto[];
}

@Get('/:id')
async find_by_id(@Param('id') id: string) {
return {
clientDescription: 'Description',
clientId: 'clientId',
clientSecret: 'ClientSecret',
clientName: 'Rebecca Project 123',
redirectUris: ['http://example.com/callback'],
postLogoutRedirectUris: ['http://example.com/logout'],
scope: ['firstname', 'lastname'],
} satisfies CreateOidcClientDto;
}

@Post()
async create(@Body() createOidcClientDto: CreateOidcClientDto) {
try {
Expand All @@ -26,7 +57,7 @@ export class OidcClientController {
HttpStatus.BAD_REQUEST,
{
cause: error,
},
}
);
}
}
Expand Down
12 changes: 12 additions & 0 deletions front/src/clients/back-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const backendClient = {
getKeys,
getList,
postOidcClient,
getDashboard,
getDashboardItem,
};

async function getKeys() {
Expand All @@ -18,6 +20,16 @@ async function getList() {
return response.data;
}

async function getDashboard() {
const response = await axios.get(VITE_BASE_URL + '/oidc-clients/');
return response.data;
}

async function getDashboardItem(id: string) {
const response = await axios.get(VITE_BASE_URL + '/oidc-clients/' + id);
return response.data;
}

async function postOidcClient(data: OidcClient) {
return await axios.post(VITE_BASE_URL + '/oidc-clients', data);
}
5 changes: 4 additions & 1 deletion front/src/headers/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ function Header() {
{
iconId: 'fr-icon-user-fill',
linkProps: {
to: '/connexion',
// NOTE(douglasduteil): use mocked data for now
// Will be replaced by
// to: '/connexion',
to: '/dashboard',
},
text: 'Se connecter',
},
Expand Down
25 changes: 6 additions & 19 deletions front/src/providers/connectedSpaces/EspaceConnected.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
import { useContext } from 'react';
import Title1 from '../../titles/Title1';
import { KeyProductionData } from '../details/KeyProductionData';
import { ProviderKey } from '../details/ProviderKey';
import { ProviderName } from '../details/ProviderName';
import { ProviderScope } from '../details/ProviderScope';
import { SideMenu } from '../details/ProviderSideMenu';
import { ProviderUrl } from '../details/ProviderUrl';
import { ProviderUrlDeco } from '../details/ProviderUrlDeco';
import { ProviderValidation } from '../details/ProviderValidation';
import { OidcClientFormContext } from '../details/oidc-client-form.context';
import { OidcClient } from '../../types';
import { useState } from 'react';
import { SideMenu } from '../details/ProviderSideMenu';

export const EspaceConnected = () => {
const [oidcClientForm, setOidcClientForm] = useState<OidcClient>({
clientName: '',
clientDescription: '',
clientId: '',
clientSecret: '',
redirectUris: [],
postLogoutRedirectUris: [],
scope: [],
});
const { oidcClientForm: {clientName} } = useContext(OidcClientFormContext);
return (
<OidcClientFormContext.Provider
value={{
setOidcClientForm,
}}
>
<>
<div className="fr-container">
<Title1 title="Espace connecté" />
<Title1>{clientName}</Title1>
<div className="fr-container--fluid">
<div className="fr-grid-row fr-grid-row--gutters"></div>
</div>
Expand All @@ -47,6 +34,6 @@ export const EspaceConnected = () => {
</div>
</div>
</div>
</OidcClientFormContext.Provider>
</>
);
};
23 changes: 12 additions & 11 deletions front/src/providers/details/ProviderDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { SideMenu } from './ProviderSideMenu';
import { ProviderKey } from './ProviderKey';
import { ProviderUrl } from './ProviderUrl';
import { ProviderScope } from './ProviderScope';
import { KeyProductionData } from './KeyProductionData';
import { ProviderUrlDeco } from './ProviderUrlDeco';
import Title1 from '../../titles/Title1';
import { OidcClientFormContext } from './oidc-client-form.context';
import { OidcClient } from '../../types';
import { useState } from 'react';
import CardInfos from '../../cards/CardInfos';
import monImage from '../../images/test-image.png';
import monImage2 from '../../images/test-image2.png';
import { ProviderValidation } from './ProviderValidation';
import Title1 from '../../titles/Title1';
import { OidcClient } from '../../types';
import { KeyProductionData } from './KeyProductionData';
import { ProviderKey } from './ProviderKey';
import { ProviderName } from './ProviderName';
import { ProviderScope } from './ProviderScope';
import { SideMenu } from './ProviderSideMenu';
import { ProviderUrl } from './ProviderUrl';
import { ProviderUrlDeco } from './ProviderUrlDeco';
import { ProviderValidation } from './ProviderValidation';
import { OidcClientFormContext } from './oidc-client-form.context';

export function ProviderDetails() {
const [oidcClientForm, setOidcClientForm] = useState<OidcClient>({
Expand All @@ -28,11 +28,12 @@ export function ProviderDetails() {
return (
<OidcClientFormContext.Provider
value={{
oidcClientForm,
setOidcClientForm,
}}
>
<div className="fr-container">
<Title1 title="Implémentation" />
<Title1>Implémentation</Title1>
<div className="fr-container">
<div className="fr-grid-row fr-grid-row--gutters">
<CardInfos
Expand Down
19 changes: 13 additions & 6 deletions front/src/providers/details/ProviderKey.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Input } from '@codegouvfr/react-dsfr/Input';
import { Button } from '@codegouvfr/react-dsfr/Button';
import { Input } from '@codegouvfr/react-dsfr/Input';
import React, { useContext, useState } from 'react';
import { backendClient } from '../../clients/back-client';
import Title2 from '../../titles/Title2';
Expand All @@ -10,17 +10,24 @@ const copyToClipBoard = (value: string) => {
};

export const ProviderKey = () => {
const [clientID, setClientID] = useState('');
const [clientSecret, setClientSecret] = useState('');
const [isShown, setIsShown] = useState(false);

const { setOidcClientForm } = useContext(OidcClientFormContext);
const { setOidcClientForm, oidcClientForm } = useContext(
OidcClientFormContext
);
const [clientID, setClientID] = useState(oidcClientForm.clientId);
const [clientSecret, setClientSecret] = useState(oidcClientForm.clientSecret);
const [isShown, setIsShown] = useState(
Boolean(oidcClientForm.clientId && oidcClientForm.clientSecret)
);

const toggleShowClientId = () => {
setIsShown((current) => !current);
};

React.useEffect(() => {
if (isShown) {
return;
}

async function fetchData() {
try {
const data = await backendClient.getKeys();
Expand Down
15 changes: 15 additions & 0 deletions front/src/providers/details/ProviderName.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import { Input } from '@codegouvfr/react-dsfr/Input';
import { ChangeEvent, useCallback, useContext } from 'react';
import { OidcClientFormContext } from './oidc-client-form.context';

export const ProviderName = () => {
const { oidcClientForm, setOidcClientForm } = useContext(
OidcClientFormContext
);
const onChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setOidcClientForm((prevState) => ({ ...prevState, clientName: value }));
}, []);

return (
<div className="fr-mb-10v">
<div className="fr-container--fluid">
<div className="fr-grid-row fr-grid-row--bottom">
<Input
className="fr-col-md-7 fr-m-1v fr-text--bold"
state={oidcClientForm.clientName === '' ? 'error' : 'default'}
stateRelatedMessage="Nom de projet obligatoire"
label="Nom du projet"
nativeInputProps={{
type: 'text',
placeholder: 'Test - date',
onChange,
required: true,
value: oidcClientForm.clientName,
}}
/>
</div>
Expand Down
14 changes: 10 additions & 4 deletions front/src/providers/details/ProviderScope.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Checkbox } from '@codegouvfr/react-dsfr/Checkbox';
import React, { ChangeEvent, useContext, useState } from 'react';
import { COLORS } from '../../constants';
import Title2 from '../../titles/Title2';
import { OidcClientFormContext } from './oidc-client-form.context';
import { OidcClient } from '../../types';
import { COLORS } from '../../constants';
import { OidcClientFormContext } from './oidc-client-form.context';

export const ProviderScope = () => {
const [scope, setScope] = useState<string[]>([]);
const { setOidcClientForm } = useContext(OidcClientFormContext);
const { setOidcClientForm, oidcClientForm } = useContext(
OidcClientFormContext
);
const [scope, setScope] = useState<string[]>(oidcClientForm.scope);

const getScopes = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) {
Expand Down Expand Up @@ -49,6 +51,7 @@ export const ProviderScope = () => {
nativeInputProps: {
name: 'checkboxes-1',
value: 'firstname',
checked: scope.includes('firstname'),
onChange: getScopes,
},
},
Expand All @@ -57,6 +60,7 @@ export const ProviderScope = () => {
nativeInputProps: {
name: 'checkboxes-1',
value: 'lastname',
checked: scope.includes('lastname'),
onChange: getScopes,
},
},
Expand All @@ -65,6 +69,7 @@ export const ProviderScope = () => {
nativeInputProps: {
name: 'checkboxes-1',
value: 'function-in-organization',
checked: scope.includes('function-in-organization'),
onChange: getScopes,
},
},
Expand All @@ -73,6 +78,7 @@ export const ProviderScope = () => {
nativeInputProps: {
name: 'checkboxes-1',
value: 'email',
checked: scope.includes('email'),
onChange: getScopes,
},
},
Expand Down
12 changes: 8 additions & 4 deletions front/src/providers/details/ProviderUrl.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Input } from '@codegouvfr/react-dsfr/Input';
import { Button } from '@codegouvfr/react-dsfr/Button';
import { Input } from '@codegouvfr/react-dsfr/Input';
import { ChangeEvent, useContext, useState } from 'react';
import Title2 from '../../titles/Title2';
import { OidcClientFormContext } from './oidc-client-form.context';

export const ProviderUrl = () => {
const [inputUrl, setInputUrl] = useState<string>('');
const [contents, setContents] = useState<string[]>([]);
const { setOidcClientForm } = useContext(OidcClientFormContext);
const { setOidcClientForm, oidcClientForm } = useContext(
OidcClientFormContext
);

const [inputUrl, setInputUrl] = useState<string>('');
const [contents, setContents] = useState<string[]>(
oidcClientForm.redirectUris
);
const handleInputChange = (e: ChangeEvent<HTMLInputElement>): void => {
setInputUrl(e.target.value);
};
Expand Down
12 changes: 8 additions & 4 deletions front/src/providers/details/ProviderUrlDeco.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Input } from '@codegouvfr/react-dsfr/Input';
import { Button } from '@codegouvfr/react-dsfr/Button';
import { Input } from '@codegouvfr/react-dsfr/Input';
import { ChangeEvent, useContext, useState } from 'react';
import { OidcClientFormContext } from './oidc-client-form.context';

export const ProviderUrlDeco = () => {
const { setOidcClientForm, oidcClientForm } = useContext(
OidcClientFormContext
);
const [inputUrl, setInputUrl] = useState<string>('');
const [contents, setContents] = useState<string[]>([]);
const { setOidcClientForm } = useContext(OidcClientFormContext);
const [contents, setContents] = useState<string[]>(
oidcClientForm.postLogoutRedirectUris
);

const handleInputChange = (e: ChangeEvent<HTMLInputElement>): void => {
setInputUrl(e.target.value);
Expand Down Expand Up @@ -34,7 +38,7 @@ export const ProviderUrlDeco = () => {
<div className="fr-grid-row fr-grid-row--bottom">
<Input
className="fr-col-md-7 fr-m-1v fr-text--bold"
label="URL de la page de redirection"
label="URL de la page de déconnexion"
nativeInputProps={{
value: inputUrl,
placeholder: 'https://',
Expand Down
8 changes: 0 additions & 8 deletions front/src/providers/details/oidc-client-form.context.ts

This file was deleted.

Loading

0 comments on commit 47c480f

Please sign in to comment.