Skip to content

Commit

Permalink
Merge pull request #1010 from Klantinteractie-Servicesysteem/pc-727-v…
Browse files Browse the repository at this point in the history
…ac-items-toevoegen

Vac items: PC-727 (toevoegen) en PC-729 (bewerken)
  • Loading branch information
nijmra authored Jan 16, 2025
2 parents 5c4224a + 1a9a8a0 commit f12cc81
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 19 deletions.
6 changes: 5 additions & 1 deletion Kiss.Bff/Config/AuthenticationSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ public static IServiceCollection AddKissAuth(this IServiceCollection services, A
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.SlidingExpiration = true;
//options.Events.OnSigningOut = (e) => e.HttpContext.RevokeRefreshTokenAsync();
options.Events.OnRedirectToAccessDenied = HandleLoggedOut;
options.Events.OnRedirectToAccessDenied = (ctx) =>
{
ctx.Response.StatusCode = StatusCodes.Status403Forbidden;
return Task.CompletedTask;
};
options.Events.OnRedirectToLogin = HandleLoggedOut;
});

Expand Down
39 changes: 39 additions & 0 deletions Kiss.Bff/Extern/Vacs/PostVacsCustomProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Kiss.Bff.Vacs
{
[ApiController]
public class PostVacsCustomProxy : ControllerBase
{
private readonly VacsProxyConfig _config;

public PostVacsCustomProxy(VacsProxyConfig config)
{
_config = config;
}

[HttpPost]
[Authorize(Policy = Policies.RedactiePolicy)]
[Route("api/vacs/api/{version}/objects")]
public IActionResult Post([FromRoute] string version, [FromBody] JsonObject node)
{
node["type"] = _config.ObjectTypeUrl;

if (node.TryGetPropertyValue("record", out var record) && record is JsonObject recordObj)
{
recordObj["typeVersion"] = _config.TypeVersion;
}

var url = $"{_config.Destination.TrimEnd('/')}/api/{version}/objects";

return new ProxyResult(() =>
{
var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = JsonContent.Create(node) };
_config.ApplyHeaders(request.Headers);
return request;
});
}
}
}
5 changes: 3 additions & 2 deletions Kiss.Bff/Extern/Vacs/VacsProxyConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ public static class VacsExtensions
{
public static IServiceCollection AddVacsProxy(this IServiceCollection services, string destination, string token, string objectTypeUrl, string typeVersion)
{
return services.AddSingleton<IKissProxyRoute>(s =>
return services.AddSingleton(s =>
{
var authorizationService = s.GetRequiredService<IAuthorizationService>();
var policyProvider = s.GetRequiredService<IAuthorizationPolicyProvider>();

return new VacsProxyConfig(destination, token, objectTypeUrl, typeVersion, authorizationService, policyProvider);
});
})
.AddSingleton<IKissProxyRoute>(s => s.GetRequiredService<VacsProxyConfig>());
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/components/ckeditor/CkEditorAsync.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ const config: EditorConfig = {
"blockQuote",
"undo",
"redo",
"insertTable",
],
table: {
defaultHeadings: { rows: 1 },
contentToolbar: ["tableColumn", "tableRow"],
},
};
</script>

Expand Down
2 changes: 2 additions & 0 deletions src/components/ckeditor/ckeditor-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export {
Link,
List,
Paragraph,
Table,
TableToolbar,
type EditorConfig,
} from "ckeditor5";

Expand Down
4 changes: 4 additions & 0 deletions src/features/search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ export type Vac = {
uuid?: string;
vraag: string;
antwoord: string;
toelichting?: string;
afdelingen?: VacAfdeling[];
trefwoorden?: { trefwoord: string }[];
status?: string;
doelgroep?: string;
};

export type Nieuwsbericht = {
Expand Down
251 changes: 237 additions & 14 deletions src/views/Beheer/vacs/VacBeheer.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,243 @@
<template>
<utrecht-heading :level="1">{{ uuid }}</utrecht-heading>

<menu>
<li>
<router-link
to="/Beheer/vacs/"
class="utrecht-button utrecht-button--secondary-action"
>
Annuleren
</router-link>
</li>
</menu>
<utrecht-heading :level="1"
>Vac {{ props.uuid ? "bewerken" : "toevoegen" }}</utrecht-heading
>

<simple-spinner v-if="loading" />

<p v-else-if="error">Er is een fout opgetreden bij het ophalen van de Vac.</p>

<beheer-form @submit="submit" v-else>
<template #formFields>
<label class="utrecht-form-label"
><span>Vraag *</span>

<input
class="utrecht-textbox utrecht-textbox--html-input"
type="text"
v-model="vac.record.data.vraag"
required
/></label>

<label class="utrecht-form-label" for="antwoord">Antwoord *</label>
<ck-editor v-model="vac.record.data.antwoord" required />

<label class="utrecht-form-label" for="toelichting">Toelichting</label>
<ck-editor v-model="vac.record.data.toelichting" />

<fieldset>
<legend>Afdelingen</legend>

<ul>
<li
v-for="(value, key) in vac.record.data.afdelingen"
:key="`afdeling_${key}`"
>
<label class="utrecht-form-label">
<input
class="utrecht-textbox utrecht-textbox--html-input"
type="text"
v-model="value.afdelingNaam"
:aria-label="`Afdeling ${key + 1}`"
/></label>
</li>
</ul>
</fieldset>

<fieldset>
<legend>Trefwoorden</legend>

<ul>
<li
v-for="(value, key) in vac.record.data.trefwoorden"
:key="`trefwoord_${key}`"
>
<label class="utrecht-form-label">
<input
class="utrecht-textbox utrecht-textbox--html-input"
type="text"
v-model="value.trefwoord"
:aria-label="`Trefwoord ${key + 1}`"
/></label>
</li>
</ul>
</fieldset>

<p>Velden met (*) zijn verplicht</p>
</template>

<template #formMenuListItems>
<li>
<router-link
to="/Beheer/vacs/"
class="utrecht-button utrecht-button--secondary-action"
>
Annuleren
</router-link>
</li>

<li>
<utrecht-button appearance="primary-action-button" type="submit">
Opslaan
</utrecht-button>
</li>
</template>
</beheer-form>
</template>

<script setup lang="ts">
import { Heading as UtrechtHeading } from "@utrecht/component-library-vue";
import { onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router";
import {
Heading as UtrechtHeading,
Button as UtrechtButton,
} from "@utrecht/component-library-vue";
import SimpleSpinner from "@/components/SimpleSpinner.vue";
import CkEditor from "@/components/ckeditor";
import BeheerForm from "@/components/beheer/BeheerForm.vue";
import { fetchLoggedIn, parseJson, throwIfNotOk } from "@/services";
import type { Vac } from "@/features/search/types";
import { toast } from "@/stores/toast";
type VacObject = {
record: {
startAt: string;
data: Vac;
index?: number;
correctionFor?: number;
};
};
const vacObjectenUrl = "/api/vacs/api/v2/objects";
const props = defineProps<{ uuid?: string }>();
const router = useRouter();
const loading = ref(false);
const error = ref(false);
defineProps<{ uuid?: string }>();
const afdelingen = Array.from({ length: 5 }, () => ({ afdelingNaam: "" }));
const trefwoorden = Array.from({ length: 10 }, () => ({ trefwoord: "" }));
const vac = ref<VacObject>({
record: {
startAt: new Date().toISOString().substring(0, 10),
data: {
vraag: "",
antwoord: "",
afdelingen,
toelichting: "",
trefwoorden,
},
},
});
// Update with fetched data while remaining array length
watch(
() => ({
afdelingData: vac.value.record.data.afdelingen,
trefwoordData: vac.value.record.data.trefwoorden,
}),
({ afdelingData, trefwoordData }) => {
vac.value.record.data.afdelingen = [
...(afdelingData || []),
...afdelingen,
].slice(0, afdelingen.length);
vac.value.record.data.trefwoorden = [
...(trefwoordData || []),
...trefwoorden,
].slice(0, trefwoorden.length);
},
{ once: true },
);
const showError = () => {
toast({
text: "Er is een fout opgetreden bij het opslaan van de Vac. Probeer het later opnieuw.",
type: "error",
});
};
const handleSuccess = () => {
toast({
text: "De Vac is opgeslagen.",
});
router.push("/Beheer/vacs");
};
const submit = async () => {
loading.value = true;
const createPayload = () => {
const body = {
...vac.value,
...{
record: {
...vac.value.record,
data: {
...vac.value.record.data,
afdelingen: vac.value.record.data.afdelingen?.filter(
(afdeling) => afdeling.afdelingNaam.trim().length,
),
trefwoorden: vac.value.record.data.trefwoorden?.filter(
(trefwoord) => trefwoord.trefwoord.trim().length,
),
status: "actief",
doelgroep: "eu-burger",
},
correctionFor: props.uuid ? vac.value.record.index : undefined,
},
},
};
return JSON.stringify(body);
};
const result = await fetchLoggedIn(
`${vacObjectenUrl}/${props.uuid ? props.uuid : ""}`,
{
method: props.uuid ? "PUT" : "POST",
headers: {
"Content-Type": "application/json",
},
body: createPayload(),
},
).finally(() => (loading.value = false));
result.ok ? handleSuccess() : showError();
};
onMounted(() => {
if (!props.uuid) return;
loading.value = true;
fetchLoggedIn(`${vacObjectenUrl}/${props.uuid}`)
.then(throwIfNotOk)
.then(parseJson)
.then((result: VacObject) => (vac.value = result))
.catch(() => (error.value = true))
.finally(() => (loading.value = false));
});
</script>

<style lang="scss" scoped>
fieldset {
legend {
color: var(--utrecht-form-label-color);
font-size: var(--utrecht-form-label-font-size);
font-weight: var(--utrecht-form-label-font-weight);
margin-block-end: var(--spacing-default);
}
ul {
display: flex;
flex-direction: column;
gap: var(--spacing-default);
list-style: disc;
padding-inline-start: var(--spacing-default);
}
}
</style>
15 changes: 13 additions & 2 deletions src/views/Beheer/vacs/VacsBeheer.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
<template>
<utrecht-heading :level="1">Vacs</utrecht-heading>
<div class="header-wrapper">
<utrecht-heading :level="1">Vacs</utrecht-heading>

<router-link
to="/Beheer/vac/"
title="Toevoegen"
class="utrecht-button utrecht-button--primary-action icon icon-after plus icon-only"
>
</router-link>
</div>

<simple-spinner v-if="loading" />

<div v-else-if="error">Er is een fout opgetreden.</div>
<div v-else-if="error">
Er is een fout opgetreden bij het ophalen van de Vacs.
</div>

<ul v-else>
<li v-for="vac in vacs" :key="vac.uuid" class="listItem">
Expand Down

0 comments on commit f12cc81

Please sign in to comment.