Skip to content

Commit

Permalink
chore: frontend listing of docker images #369
Browse files Browse the repository at this point in the history
  • Loading branch information
bsilkyn committed Apr 25, 2024
1 parent 522cfc6 commit 1e1949f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 14 deletions.
2 changes: 2 additions & 0 deletions frontend/src/components/admin/LazyDataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { onMounted, watch, ref, defineExpose, toRef } from "vue";
import { PaginatorResponse } from '@/types/filter/Paginator.ts'
import { usePaginator } from '@/composables/filters/paginator.ts';
import { Filter } from "@/types/filter/Filter.ts";
import Column from "primevue/column";
/* Properties */
const props = defineProps<{
Expand Down Expand Up @@ -98,6 +99,7 @@ defineExpose({fetch})
</template>
<template #empty>No matching data.</template>
<template #loading>Loading data. Please wait.</template>
<Column selectionMode="multiple" headerStyle="width: 3rem" class="justify-content-center"></Column>
<slot />
</DataTable>
</div>
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/composables/services/docker.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,30 @@ import { Response } from "@/types/Response.ts";
import { endpoints } from '@/config/endpoints.ts';
import { type Ref, ref } from "vue";
import { Filter } from "@/types/filter/Filter.ts";
import { create, getPaginatedList } from "@/composables/services/helpers.ts";
import {create, getList, getPaginatedList} from "@/composables/services/helpers.ts";
import {PaginatorResponse} from "@/types/filter/Paginator.ts";


interface DockerImagesState {
pagination: Ref<PaginatorResponse<DockerImage> | null>;
dockerImages: Ref<DockerImage[] | null>;
response: Ref<Response | null>;
getDockerImages: () => Promise<void>;
searchDockerImages: (filters: Filter, page: number, pageSize: number) => Promise<void>;
createDockerImage: (dockerData: DockerImage, file: File) => Promise<void>;
}


export function useDockerImages(): DockerImagesState {
const pagination = ref<PaginatorResponse<DockerImage> | null>(null);
const dockerImages = ref<DockerImage[] | null>(null);
const response = ref<Response | null>(null);

async function getDockerImages(): Promise<void> {
const endpoint = endpoints.dockerImages.index;
await getList<DockerImage>(endpoint, dockerImages, DockerImage.fromJSON);
}

async function searchDockerImages(filters: Filter, page: number, pageSize: number): Promise<void> {
const endpoint = endpoints.dockerImages.search;
await getPaginatedList<DockerImage>(endpoint, filters, page, pageSize, pagination, DockerImage.fromJSON);
Expand All @@ -41,8 +49,10 @@ export function useDockerImages(): DockerImagesState {

return {
pagination,
dockerImages,
response,

getDockerImages,
searchDockerImages,
createDockerImage
}
Expand Down
17 changes: 16 additions & 1 deletion frontend/src/types/filter/Filter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type LocationQuery } from 'vue-router';
import {type LocationQuery} from 'vue-router';

export type UserFilter = {
id: string;
Expand All @@ -12,6 +12,12 @@ export type CourseFilter = {
years: string[];
} & Filter;

export type DockerImageFilter = {
id: string;
name: string;
owner: string;
} & Filter

export interface Filter {
search: string;
[key: string]: string | string[];
Expand Down Expand Up @@ -61,6 +67,15 @@ export function getCourseFilters(query: LocationQuery): CourseFilter {
return filters;
}

export function getDockerImageFilters(query:LocationQuery): DockerImageFilter {
return {
search: query.search?.toString() ?? '',
id: query.id?.toString() ?? '',
name: query.id?.toString() ?? '',
owner: query.id?.toString() ?? '',
};
}

/**
* Get the query list.
*
Expand Down
58 changes: 48 additions & 10 deletions frontend/src/views/admin/DockerImagesView.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
<script setup lang="ts">
import DataTable from 'primevue/datatable';
import FileUpload, { type FileUploadUploaderEvent } from 'primevue/fileupload';
import InputText from 'primevue/inputtext';
import InputSwitch from 'primevue/inputswitch';
import SelectButton from 'primevue/selectbutton';
import AdminLayout from '@/components/layout/admin/AdminLayout.vue';
import Title from '@/components/layout/Title.vue';
import Body from '@/components/layout/Body.vue';
import LazyDataTable from '@/components/admin/LazyDataTable.vue';
import { useDockerImages } from '@/composables/services/docker.service.ts';
import { useFilter } from "@/composables/filters/filter.ts";
import { useI18n } from 'vue-i18n';
import { ref } from 'vue';
import {DockerImage} from "@/types/DockerImage.ts";
import { useRoute } from "vue-router";
import { DockerImage } from "@/types/DockerImage.ts";
import { getDockerImageFilters } from "@/types/filter/Filter.ts";
import type {Role} from "@/types/users/User.ts";
import InputIcon from "primevue/inputicon";
import MultiSelect from "primevue/multiselect";
import Column from "primevue/column";
import IconField from "primevue/iconfield";
/* Injection */
const { t } = useI18n();
const { pagination, searchDockerImages, createDockerImage } = useDockerImages();
const { query } = useRoute();
const { pagination, dockerImages, getDockerImages, searchDockerImages, createDockerImage } = useDockerImages();
const { filter, onFilter } = useFilter(getDockerImageFilters(query));
const addItem = ref<DockerImage>(DockerImage.blankDockerImage())
const selectOptions = ref(['admin.list', 'admin.add']);
const selected = ref<string>(t(selectOptions.value[0]));
const columns = ref([
{ field: 'id', header: 'admin.users.id' },
{ field: 'username', header: 'admin.users.username' },
{ field: 'email', header: 'admin.users.email' },
{ field: 'roles', header: 'admin.users.roles' },
]);
const upload = async (event: FileUploadUploaderEvent): Promise<void> => {
const files: File[] = event.files as File[];
await createDockerImage(addItem.value, files[0]);
Expand All @@ -36,13 +53,34 @@ const upload = async (event: FileUploadUploaderEvent): Promise<void> => {
<Body>
<SelectButton class="mb-3 gap-3" v-model="selected" :options="selectOptions.map(t)" />
<div v-if="selected === t(selectOptions[0])">
<DataTable
:value="pagination?.results"
lazy
paginator
v-mode:f>

</DataTable>
<LazyDataTable
:pagination="pagination"
:entities="dockerImages"
:get="getDockerImages"
:search="searchDockerImages"
:filter="filter"
:on-filter="onFilter">
<Column
v-for="column in columns"
:key="column.field"
:field="column.field"
:header="t(column.header)"
:show-filter-menu="false"
:style="{ minWidth: '14rem' }"
>
<template #filter>
<IconField
iconPosition="left"
class="flex align-items-center"
>
<InputIcon>
<i class="pi pi-search flex justify-content-center" />
</InputIcon>
<InputText v-model="filter[column.field]" :placeholder="t('admin.search.search')" />
</IconField>
</template>
</Column>
</LazyDataTable>
</div>
<div v-else>
<InputText class="mb-3 gap-3" v-model:model-value="addItem.name" :placeholder="t('admin.docker_images.name')" />
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/views/admin/UsersView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script setup lang="ts">
import DataTable, { type DataTableSelectAllChangeEvent } from 'primevue/datatable';
import Column from 'primevue/column';
import Dialog from 'primevue/dialog';
import InputSwitch from 'primevue/inputswitch';
Expand Down Expand Up @@ -156,7 +155,6 @@ const saveItem = async (): Promise<void> => {
</template>
<template #empty>No matching data.</template>
<template #loading>Loading data. Please wait.</template>
<Column selectionMode="multiple" headerStyle="width: 3rem" class="justify-content-center"></Column>
<Column
v-for="column in columns"
:key="column.field"
Expand Down

0 comments on commit 1e1949f

Please sign in to comment.