Skip to content

Commit

Permalink
add a CHEFS Admin UX for approving External APIs.
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Sherman <[email protected]>
  • Loading branch information
usingtechnology committed Jun 8, 2024
1 parent 0f2b93a commit 29d2ff6
Show file tree
Hide file tree
Showing 18 changed files with 663 additions and 16 deletions.
308 changes: 308 additions & 0 deletions app/frontend/src/components/admin/AdminAPIsTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
<script>
import { mapActions, mapState } from 'pinia';
import { i18n } from '~/internationalization';
import { useAdminStore } from '~/store/admin';
import { useFormStore } from '~/store/form';
import { Ministries } from '~/utils/constants';
export default {
data() {
return {
loading: true,
search: '',
editDialog: {
title: '',
item: {
id: null,
formName: null,
ministry: null,
ministryText: null,
name: null,
endpointUrl: null,
code: null,
},
show: false,
},
};
},
computed: {
...mapState(useAdminStore, ['externalAPIList', 'externalAPIStatusCodes']),
...mapState(useFormStore, ['isRTL', 'lang']),
ministryList() {
return Ministries.map((ministry) => ({
id: ministry.id,
text: i18n.t(`trans.ministries.${ministry.id}`),
}));
},
headers() {
return [
{
title: i18n.t('trans.adminAPIsTable.ministry'),
align: 'start',
key: 'ministry',
},
{
title: i18n.t('trans.adminAPIsTable.formName'),
align: 'start',
key: 'formName',
},
{
title: i18n.t('trans.adminAPIsTable.name'),
align: 'start',
key: 'name',
},
{
title: i18n.t('trans.adminAPIsTable.endpointUrl'),
align: 'start',
key: 'endpointUrl',
},
{
title: i18n.t('trans.adminAPIsTable.display'),
align: 'start',
key: 'display',
},
{
title: i18n.t('trans.adminAPIsTable.actions'),
align: 'end',
key: 'actions',
filterable: false,
sortable: false,
},
];
},
},
async mounted() {
await this.getExternalAPIStatusCodes();
await this.getExternalAPIs();
this.loading = false;
},
methods: {
...mapActions(useAdminStore, [
'getExternalAPIs',
'updateExternalAPI',
'getExternalAPIStatusCodes',
]),
resetEditDialog() {
this.editDialog = {
title: '',
item: {
id: null,
formName: null,
ministry: null,
name: null,
endpointUrl: null,
code: null,
},
show: false,
};
},
handleEdit(item) {
this.resetEditDialog();
this.editDialog.item = { ...item };
this.editDialog.item.ministryText = this.ministryList.find(
(x) => x.id === item.ministry
)['text'];
this.editDialog.title = i18n.t('trans.adminAPIsTable.editTitle');
this.editDialog.show = true;
},
async saveItem() {
await this.updateExternalAPI(
this.editDialog.item.id,
this.editDialog.item
);
// reset and close on success...
this.resetEditDialog();
// reload data...
this.loading = true;
await this.getExternalAPIs();
this.loading = false;
},
},
};
</script>

<template>
<div>
<v-row no-gutters>
<v-spacer />
<v-col cols="12">
<!-- search input -->
<div
class="submissions-search"
:class="isRTL ? 'float-left' : 'float-right'"
>
<v-text-field
v-model="search"
density="compact"
variant="underlined"
:label="$t('trans.adminAPIsTable.search')"
append-inner-icon="mdi-magnify"
single-line
hide-details
class="pb-5"
:class="{ 'dir-rtl': isRTL, label: isRTL }"
:lang="lang"
/>
</div>
</v-col>
</v-row>

<!-- table header -->
<v-data-table
class="submissions-table"
hover
:headers="headers"
item-key="title"
:items="externalAPIList"
:search="search"
:loading="loading"
:loading-text="$t('trans.adminAPIsTable.loadingText')"
:lang="lang"
>
<template #item.ministry="{ item }">
{{ ministryList.find((x) => x.id === item.ministry)['text'] }}
</template>
<template #item.formName="{ item }">
{{ item.formName }}
</template>
<template #item.name="{ item }">
{{ item.name }}
</template>
<template #item.endpointUrl="{ item }">
{{ item.endpointUrl }}
</template>
<template #item.display="{ item }">
{{ item.display }}
</template>
<template #item.actions="{ item }">
<span>
<v-tooltip location="bottom">
<template #activator="{ props }">
<v-btn
color="primary"
class="mx-1"
icon
v-bind="props"
variant="text"
:title="$t('trans.adminAPIsTable.edit')"
@click="handleEdit(item)"
>
<v-icon icon="mdi:mdi-pencil"></v-icon>
</v-btn>
</template>
<span :lang="lang">{{ $t('trans.adminAPIsTable.edit') }}</span>
</v-tooltip>
</span>
</template>
</v-data-table>
</div>
<BaseDialog
v-model="editDialog.show"
eager
type="CONTINUE"
show-close-button
:class="{ 'dir-rtl': isRTL }"
:title="editDialog.title"
width="1200"
@continue-dialog="saveItem"
@close-dialog="editDialog.show = false"
><template #title>{{ editDialog.title }}</template>
<template #text>
<v-form ref="form" @submit="saveItem()" @submit.prevent>
<v-text-field
v-model="editDialog.item.ministryText"
aria-readonly="true"
:readonly="true"
density="compact"
solid
variant="outlined"
:label="$t('trans.adminAPIsTable.ministry')"
:lang="lang"
/>

<v-text-field
v-model="editDialog.item.formName"
aria-readonly="true"
:readonly="true"
density="compact"
solid
variant="outlined"
:label="$t('trans.adminAPIsTable.formName')"
:lang="lang"
/>

<v-text-field
v-model="editDialog.item.name"
aria-readonly="true"
:readonly="true"
density="compact"
solid
variant="outlined"
:label="$t('trans.adminAPIsTable.name')"
:lang="lang"
/>

<v-text-field
v-model="editDialog.item.endpointUrl"
aria-readonly="true"
:readonly="true"
density="compact"
solid
variant="outlined"
:label="$t('trans.adminAPIsTable.endpointUrl')"
:lang="lang"
/>

<v-select
v-model="editDialog.item.code"
:items="externalAPIStatusCodes"
item-title="display"
item-value="code"
:label="$t('trans.adminAPIsTable.display')"
density="compact"
solid
variant="outlined"
:lang="lang"
></v-select>
</v-form>
</template>
<template #button-text-continue>
<span :lang="lang">{{ $t('trans.externalAPI.save') }}</span>
</template>
</BaseDialog>
</template>
<style scoped>
/* TODO: Global Style! */
.submissions-search {
width: 100%;
}
@media (min-width: 600px) {
.submissions-search {
max-width: 20em;
float: right;
}
}
@media (max-width: 599px) {
.submissions-search {
padding-left: 16px;
padding-right: 16px;
}
}
.submissions-table {
clear: both;
}
@media (max-width: 1263px) {
.submissions-table :deep(th) {
vertical-align: top;
}
}
.submissions-table :deep(thead tr th) {
font-weight: normal;
color: #003366 !important;
font-size: 1.1em;
}
</style>
6 changes: 6 additions & 0 deletions app/frontend/src/components/admin/AdminPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { mapState } from 'pinia';
import AdminFormsTable from '~/components/admin/AdminFormsTable.vue';
import AdminUsersTable from '~/components/admin/AdminUsersTable.vue';
import AdminAPIsTable from '~/components/admin/AdminAPIsTable.vue';
import Dashboard from '~/components/admin/Dashboard.vue';
import Developer from '~/components/admin/Developer.vue';
import FormComponentsProactiveHelp from '~/components/admin/FormComponentsProactiveHelp.vue';
Expand All @@ -13,6 +14,7 @@ export default {
components: {
AdminFormsTable,
AdminUsersTable,
AdminAPIsTable,
Dashboard,
Developer,
FormComponentsProactiveHelp,
Expand Down Expand Up @@ -41,6 +43,7 @@ export default {
<v-tabs v-model="tab" :class="{ 'dir-rtl': isRTL }">
<v-tab value="forms" :lang="lang">{{ $t('trans.adminPage.forms') }}</v-tab>
<v-tab value="users" :lang="lang">{{ $t('trans.adminPage.users') }}</v-tab>
<v-tab value="apis" :lang="lang">{{ $t('trans.adminPage.apis') }}</v-tab>
<v-tab value="developer" :lang="lang">{{
$t('trans.adminPage.developer')
}}</v-tab>
Expand All @@ -60,6 +63,9 @@ export default {
<v-window-item value="users">
<AdminUsersTable />
</v-window-item>
<v-window-item value="apis">
<AdminAPIsTable />
</v-window-item>
<v-window-item value="developer">
<Developer />
</v-window-item>
Expand Down
Loading

0 comments on commit 29d2ff6

Please sign in to comment.