forked from geolba/tethys.backend
Arno Kaimbacher
b06ccae603
- mail_settings_controller for setting smtp settings - added view ror rjecting dataset for editor - added new model AppConfig for stroing appwide config values - better validate_chesum.ts command with process chunking - added vue3 apps 'BasicSettings' like email, profile settings - started with 2 multilingual capabilities - npm updates
273 lines
10 KiB
Vue
273 lines
10 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref } from 'vue';
|
|
// import { MainService } from '@/Stores/main';
|
|
// import { StyleService } from '@/Stores/style.service';
|
|
import { mdiTrashCan } from '@mdi/js';
|
|
import { mdiDragVariant } from '@mdi/js';
|
|
import BaseIcon from '@/Components/BaseIcon.vue';
|
|
// import CardBoxModal from '@/Components/CardBoxModal.vue';
|
|
// import TableCheckboxCell from '@/Components/TableCheckboxCell.vue';
|
|
// import BaseLevel from '@/Components/BaseLevel.vue';
|
|
import BaseButtons from '@/Components/BaseButtons.vue';
|
|
import BaseButton from '@/Components/BaseButton.vue';
|
|
// import UserAvatar from '@/Components/UserAvatar.vue';
|
|
// import Person from 'App/Models/Person';
|
|
import { Person } from '@/Dataset';
|
|
import Draggable from 'vuedraggable';
|
|
import FormControl from '@/Components/FormControl.vue';
|
|
|
|
const props = defineProps({
|
|
checkable: Boolean,
|
|
persons: {
|
|
type: Array<Person>,
|
|
default: () => [],
|
|
},
|
|
relation: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
contributortypes: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
errors: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
});
|
|
|
|
// const styleService = StyleService();
|
|
// const mainService = MainService();
|
|
// const items = computed(() => props.persons);
|
|
|
|
const items = computed({
|
|
get() {
|
|
return props.persons;
|
|
},
|
|
// setter
|
|
set(value) {
|
|
// Note: we are using destructuring assignment syntax here.
|
|
|
|
props.persons.length = 0;
|
|
props.persons.push(...value);
|
|
},
|
|
});
|
|
|
|
// const isModalActive = ref(false);
|
|
// const isModalDangerActive = ref(false);
|
|
const perPage = ref(5);
|
|
const currentPage = ref(0);
|
|
// const checkedRows = ref([]);
|
|
|
|
const itemsPaginated = computed({
|
|
get() {
|
|
return items.value.slice(perPage.value * currentPage.value, perPage.value * (currentPage.value + 1));
|
|
},
|
|
// setter
|
|
set(value) {
|
|
// Note: we are using destructuring assignment syntax here.
|
|
|
|
props.persons.length = 0;
|
|
props.persons.push(...value);
|
|
},
|
|
});
|
|
|
|
const numPages = computed(() => Math.ceil(items.value.length / perPage.value));
|
|
|
|
const currentPageHuman = computed(() => currentPage.value + 1);
|
|
|
|
const pagesList = computed(() => {
|
|
const pagesList: Array<number> = [];
|
|
|
|
for (let i = 0; i < numPages.value; i++) {
|
|
pagesList.push(i);
|
|
}
|
|
|
|
return pagesList;
|
|
});
|
|
|
|
const removeAuthor = (key: number) => {
|
|
items.value.splice(key, 1);
|
|
};
|
|
|
|
// const remove = (arr, cb) => {
|
|
// const newArr = [];
|
|
|
|
// arr.forEach((item) => {
|
|
// if (!cb(item)) {
|
|
// newArr.push(item);
|
|
// }
|
|
// });
|
|
|
|
// return newArr;
|
|
// };
|
|
|
|
// const checked = (isChecked, client) => {
|
|
// if (isChecked) {
|
|
// checkedRows.value.push(client);
|
|
// } else {
|
|
// checkedRows.value = remove(checkedRows.value, (row) => row.id === client.id);
|
|
// }
|
|
// };
|
|
</script>
|
|
|
|
<template>
|
|
<!-- <CardBoxModal v-model="isModalActive" title="Sample modal">
|
|
<p>Lorem ipsum dolor sit amet <b>adipiscing elit</b></p>
|
|
<p>This is sample modal</p>
|
|
</CardBoxModal>
|
|
|
|
<CardBoxModal v-model="isModalDangerActive" large-title="Please confirm" button="danger" has-cancel>
|
|
<p>Lorem ipsum dolor sit amet <b>adipiscing elit</b></p>
|
|
<p>This is sample modal</p>
|
|
</CardBoxModal> -->
|
|
|
|
<!-- <div v-if="checkedRows.length" class="p-3 bg-gray-100/50 dark:bg-slate-800">
|
|
<span v-for="checkedRow in checkedRows" :key="checkedRow.id"
|
|
class="inline-block px-2 py-1 rounded-sm mr-2 text-sm bg-gray-100 dark:bg-slate-700">
|
|
{{ checkedRow.name }}
|
|
</span>
|
|
</div> -->
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<!-- <th v-if="checkable" /> -->
|
|
<th />
|
|
<th scope="col">Sort</th>
|
|
<th scope="col">Id</th>
|
|
<!-- <th class="hidden lg:table-cell"></th> -->
|
|
<th>First Name</th>
|
|
<th>Last Name</th>
|
|
<th>Email</th>
|
|
<th scope="col" v-if="Object.keys(contributortypes).length">
|
|
<span>Type</span>
|
|
</th>
|
|
|
|
<!-- <th>Name Type</th> -->
|
|
<!-- <th>Progress</th> -->
|
|
<!-- <th>Created</th> -->
|
|
<th />
|
|
</tr>
|
|
</thead>
|
|
<!-- <tbody> -->
|
|
<!-- <tr v-for="(client, index) in itemsPaginated" :key="client.id"> -->
|
|
<draggable id="galliwasery" tag="tbody" v-model="items" item-key="id">
|
|
<template #item="{ index, element }">
|
|
<tr>
|
|
<td class="drag-icon">
|
|
<BaseIcon :path="mdiDragVariant" />
|
|
</td>
|
|
<td scope="row">{{ index + 1 }}</td>
|
|
<td data-label="Id">{{ element.id }}</td>
|
|
<!-- <TableCheckboxCell v-if="checkable" @checked="checked($event, client)" /> -->
|
|
<!-- <td v-if="element.name" class="border-b-0 lg:w-6 before:hidden hidden lg:table-cell">
|
|
<UserAvatar :username="element.name" class="w-24 h-24 mx-auto lg:w-6 lg:h-6" />
|
|
</td> -->
|
|
<td data-label="First Name">
|
|
<!-- {{ element.first_name }} -->
|
|
<FormControl
|
|
required
|
|
v-model="element.first_name"
|
|
type="text" :is-read-only="element.status==true"
|
|
placeholder="[FIRST NAME]"
|
|
>
|
|
<div
|
|
class="text-red-400 text-sm"
|
|
v-if="errors && Array.isArray(errors[`${relation}.${index}.first_name`])"
|
|
>
|
|
{{ errors[`${relation}.${index}.first_name`].join(', ') }}
|
|
</div>
|
|
</FormControl>
|
|
</td>
|
|
<td data-label="Last Name">
|
|
<FormControl
|
|
required
|
|
v-model="element.last_name"
|
|
type="text" :is-read-only="element.status==true"
|
|
placeholder="[LAST NAME]"
|
|
>
|
|
<div
|
|
class="text-red-400 text-sm"
|
|
v-if="errors && Array.isArray(errors[`${relation}.${index}.last_name`])"
|
|
>
|
|
{{ errors[`${relation}.${index}.last_name`].join(', ') }}
|
|
</div>
|
|
</FormControl>
|
|
</td>
|
|
<td data-label="Email">
|
|
<FormControl
|
|
required
|
|
v-model="element.email"
|
|
type="text" :is-read-only="element.status==true"
|
|
placeholder="[EMAIL]"
|
|
>
|
|
<div
|
|
class="text-red-400 text-sm"
|
|
v-if="errors && Array.isArray(errors[`${relation}.${index}.email`])"
|
|
>
|
|
{{ errors[`${relation}.${index}.email`].join(', ') }}
|
|
</div>
|
|
</FormControl>
|
|
</td>
|
|
<td v-if="Object.keys(contributortypes).length">
|
|
<!-- <select type="text" v-model="element.pivot.contributor_type">
|
|
<option v-for="(option, i) in contributortypes" :value="option" :key="i">
|
|
{{ option }}
|
|
</option>
|
|
</select> -->
|
|
<FormControl
|
|
required
|
|
v-model="element.pivot_contributor_type"
|
|
type="select"
|
|
:options="contributortypes"
|
|
placeholder="[relation type]"
|
|
>
|
|
<div
|
|
class="text-red-400 text-sm"
|
|
v-if="errors && Array.isArray(errors[`${relation}.${index}.pivot_contributor_type`])"
|
|
>
|
|
{{ errors[`${relation}.${index}.pivot_contributor_type`].join(', ') }}
|
|
</div>
|
|
</FormControl>
|
|
</td>
|
|
<!-- <td data-label="Name Type">
|
|
{{ client.name_type }}
|
|
</td> -->
|
|
<!-- <td data-label="Orcid">
|
|
{{ client.identifier_orcid }}
|
|
</td> -->
|
|
<!-- <td data-label="Progress" class="lg:w-32">
|
|
<progress class="flex w-2/5 self-center lg:w-full" max="100" v-bind:value="client.progress">
|
|
{{ client.progress }}
|
|
</progress>
|
|
</td> -->
|
|
<td class="before:hidden lg:w-1 whitespace-nowrap">
|
|
<BaseButtons type="justify-start lg:justify-end" no-wrap>
|
|
<!-- <BaseButton color="info" :icon="mdiEye" small @click="isModalActive = true" /> -->
|
|
<BaseButton color="danger" :icon="mdiTrashCan" small @click.prevent="removeAuthor(index)" />
|
|
</BaseButtons>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
</draggable>
|
|
<!-- </tbody> -->
|
|
</table>
|
|
<!-- :class="[ pagesList.length > 1 ? 'block' : 'hidden']" -->
|
|
<div class="p-3 lg:px-6 border-t border-gray-100 dark:border-slate-800">
|
|
<!-- <BaseLevel>
|
|
<BaseButtons>
|
|
<BaseButton
|
|
v-for="page in pagesList"
|
|
:key="page"
|
|
:active="page === currentPage"
|
|
:label="page + 1"
|
|
small
|
|
:outline="styleService.darkMode"
|
|
@click="currentPage = page"
|
|
/>
|
|
</BaseButtons>
|
|
<small>Page {{ currentPageHuman }} of {{ numPages }}</small>
|
|
</BaseLevel> -->
|
|
</div>
|
|
</template> |