Compare commits
11 Commits
99a28f44dd
...
5661d66770
Author | SHA1 | Date |
---|---|---|
|
5661d66770 | |
|
0a8ecedb0f | |
|
fd9aff25fe | |
|
c65a25ed2a | |
|
ced2d577c0 | |
|
aafef695aa | |
|
44a39fc5a8 | |
|
46a353d674 | |
|
fed0e95f14 | |
|
d1dfcb3a04 | |
|
7f9be4262c |
|
@ -2,7 +2,7 @@
|
||||||
<label class="flex flex-col items-start group" :for="id" :class="sizeClass(size)">
|
<label class="flex flex-col items-start group" :for="id" :class="sizeClass(size)">
|
||||||
<f-label v-if="label" :required="false" :value="label"></f-label>
|
<f-label v-if="label" :required="false" :value="label"></f-label>
|
||||||
<span class="relative flex-none flex" :class="{'pr-8': hint, [fieldHeight]: true}">
|
<span class="relative flex-none flex" :class="{'pr-8': hint, [fieldHeight]: true}">
|
||||||
<input :id="id" v-model="v" type="checkbox" :name="name" :value="value" :disabled="disabled" class="absolute peer invisible" @keypress="$emit('keypress', $event)" />
|
<input :id="id" v-model="v" type="checkbox" :name="name" :value="value" :disabled="disabled" class="absolute peer opacity-0" @keypress="$emit('keypress', $event)" />
|
||||||
<span
|
<span
|
||||||
class="relative cursor-pointer h-full rounded peer-focus:bg-red-500 transition-all duration-300 group-[.field-base]:w-[70px] group-[.field-sm]:w-[46px] bg-gray-700 peer-checked:bg-primary-700"
|
class="relative cursor-pointer h-full rounded peer-focus:bg-red-500 transition-all duration-300 group-[.field-base]:w-[70px] group-[.field-sm]:w-[46px] bg-gray-700 peer-checked:bg-primary-700"
|
||||||
></span>
|
></span>
|
||||||
|
@ -80,9 +80,9 @@ const v = computed({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var a = props.modelValue.filter((i) => i !== this.value);
|
var a = props.modelValue.filter((i) => i !== props.value);
|
||||||
if (v) {
|
if (v) {
|
||||||
a.push(this.value);
|
a.push(props.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('update:modelValue', a);
|
emit('update:modelValue', a);
|
||||||
|
|
|
@ -1,70 +1,40 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="fixed z-40 top-0 left-0 w-full h-full flex items-start pt-12 justify-center p-6 bg-black/60"
|
<div class="fixed z-40 top-0 left-0 w-full h-full flex items-start pt-12 justify-center p-6 bg-black/60" @click.self="emit('close')">
|
||||||
@click.self="emit('close')">
|
<div class="relative rounded-lg p-4 sm:p-8 shadow-2xl shadow-black border border-sky-700/30 bg-sky-800/10 border-solid w-full max-w-[50rem] overflow-auto backdrop-blur-lg">
|
||||||
<div
|
|
||||||
class="relative rounded-lg p-4 sm:p-8 shadow-2xl shadow-black border border-sky-700/30 bg-sky-800/10 border-solid w-full max-w-[50rem] overflow-auto backdrop-blur-lg">
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input ref="searchInput" v-model="searchString" type="text"
|
<input
|
||||||
|
ref="searchInput"
|
||||||
|
v-model="searchString"
|
||||||
|
type="text"
|
||||||
class="w-full px-3 sm:px-5 py-2 sm:py-3 pl-12 sm:pl-16 rounded-xl sm:rounded-2xl border-sky-200/40 text-sky-200 sm:text-xl placeholder-sky-200/40 bg-sky-600/20"
|
class="w-full px-3 sm:px-5 py-2 sm:py-3 pl-12 sm:pl-16 rounded-xl sm:rounded-2xl border-sky-200/40 text-sky-200 sm:text-xl placeholder-sky-200/40 bg-sky-600/20"
|
||||||
placeholder="Wer suchet, der findet …" />
|
placeholder="Wer suchet, der findet …"
|
||||||
|
/>
|
||||||
<div class="absolute flex items-center h-full top-0 left-4">
|
<div class="absolute flex items-center h-full top-0 left-4">
|
||||||
<ui-sprite src="search" class="w-5 h-5 sm:w-7 sm:h-7 text-sky-200/20" />
|
<ui-sprite src="search" class="w-5 h-5 sm:w-7 sm:h-7 text-sky-200/20" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="results !== null" class="mt-5 sm:mt-10 space-y-2">
|
<div v-if="results.hits.length" class="mt-5 sm:mt-10 space-y-2">
|
||||||
<div v-for="member in results.hits" :key="member.id">
|
<ui-search-result v-for="member in results.hits" :key="member.id" :member="member">
|
||||||
<div
|
<template #buttons>
|
||||||
class="flex items-center justify-between hover:bg-sky-600/20 transition text-sky-300 px-3 sm:px-6 py-1 sm:py-3 rounded-lg">
|
<i-link v-tooltip="`Details`" :href="member.links.show" class="inline-flex btn btn-primary btn-sm" @click="emit('close')"><ui-sprite src="eye"></ui-sprite></i-link>
|
||||||
<div class="flex space-x-2 items-center">
|
<i-link v-tooltip="`Bearbeiten`" :href="member.links.edit" class="inline-flex btn btn-warning btn-sm" @click="emit('close')"><ui-sprite src="pencil"></ui-sprite></i-link>
|
||||||
<div class="w-5 sm:w-16 flex flex-none">
|
</template>
|
||||||
<ui-age-groups icon-class="w-4 h-4 sm:w-6 sm:h-6" class="flex-col sm:flex-row"
|
</ui-search-result>
|
||||||
:member="member"></ui-age-groups>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-baseline flex-col md:flex-row">
|
|
||||||
<span class="text-lg" v-text="member.fullname"></span>
|
|
||||||
<span class="ml-2 text-xs" v-text="member.group_name"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex space-x-2">
|
|
||||||
<i-link v-tooltip="`Details`" :href="member.links.show"
|
|
||||||
class="inline-flex btn btn-primary btn-sm" @click="emit('close')"><ui-sprite
|
|
||||||
src="eye"></ui-sprite></i-link>
|
|
||||||
<i-link v-tooltip="`Bearbeiten`" :href="member.links.edit"
|
|
||||||
class="inline-flex btn btn-warning btn-sm" @click="emit('close')"><ui-sprite
|
|
||||||
src="pencil"></ui-sprite></i-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import { computed, ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import useSearch from '../../composables/useSearch.js';
|
import useSearch from '../../composables/useSearch.js';
|
||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
const { search } = useSearch();
|
const { searchString, results } = useSearch(null, { limit: 10 });
|
||||||
|
|
||||||
const realSearchString = ref('');
|
|
||||||
const results = ref(null);
|
|
||||||
const searchInput = ref(null);
|
const searchInput = ref(null);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
searchInput.value.focus();
|
searchInput.value.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchString = computed({
|
|
||||||
get: () => realSearchString.value,
|
|
||||||
set: async (v) => {
|
|
||||||
realSearchString.value = v;
|
|
||||||
|
|
||||||
if (!v.length) {
|
|
||||||
results.value = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
results.value = await search(v, [], { limit: 10 });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between hover:bg-sky-600/20 transition text-sky-300 px-3 sm:px-6 py-1 sm:py-3 rounded-lg">
|
||||||
|
<div class="flex space-x-2 items-center">
|
||||||
|
<div class="w-5 sm:w-16 flex flex-none">
|
||||||
|
<ui-age-groups icon-class="w-4 h-4 sm:w-6 sm:h-6" class="flex-col sm:flex-row" :member="member"></ui-age-groups>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-baseline flex-col md:flex-row">
|
||||||
|
<span class="text-lg" v-text="member.fullname"></span>
|
||||||
|
<span class="ml-2 text-xs" v-text="member.group_name"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex space-x-2">
|
||||||
|
<slot name="buttons"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js" setup>
|
||||||
|
defineProps({
|
||||||
|
member: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['click']);
|
||||||
|
</script>
|
|
@ -1,10 +1,15 @@
|
||||||
import {inject} from 'vue';
|
import {inject, computed, ref} from 'vue';
|
||||||
|
|
||||||
export default function useSearch() {
|
export default function useSearch(params = null, options = null) {
|
||||||
|
params = params === null ? [] : params;
|
||||||
|
options = options === null ? {} : options;
|
||||||
const axios = inject('axios');
|
const axios = inject('axios');
|
||||||
|
const results = ref({hits: []});
|
||||||
|
const realSearchString = ref('');
|
||||||
|
|
||||||
async function search(text, filters = [], options = {}) {
|
async function search(text, filters = [], options = {}) {
|
||||||
var response = await axios.post(
|
var response = await axios.post(
|
||||||
'/indexes/members/search',
|
import.meta.env.MODE === 'development' ? 'http://localhost:7700/indexes/members/search' : '/indexes/members/search',
|
||||||
{
|
{
|
||||||
q: text,
|
q: text,
|
||||||
filter: filters,
|
filter: filters,
|
||||||
|
@ -17,7 +22,28 @@ export default function useSearch() {
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearSearch() {
|
||||||
|
searchString.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchString = computed({
|
||||||
|
get: () => realSearchString.value,
|
||||||
|
set: async (v) => {
|
||||||
|
realSearchString.value = v;
|
||||||
|
|
||||||
|
if (!v.length) {
|
||||||
|
results.value = {hits: []};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.value = await search(v, params, options);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
search,
|
search,
|
||||||
|
searchString,
|
||||||
|
results,
|
||||||
|
clearSearch,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref, defineProps} from 'vue';
|
import { ref, defineProps } from 'vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useIndex.js';
|
import { indexProps, useIndex } from '../../composables/useIndex.js';
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
const {router, data, meta} = useIndex(props.data, 'activity');
|
const { router, data, meta } = useIndex(props.data, 'activity');
|
||||||
const deleting = ref(null);
|
const deleting = ref(null);
|
||||||
|
|
||||||
function remove() {
|
function remove() {
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land" required></f-select>
|
<f-select id="country" v-model="values.country" :options="countries" name="country" label="Land" required></f-select>
|
||||||
|
|
||||||
<div class="border-gray-200 shadow shadow-primary-700 p-3 shadow-[0_0_4px_gray] col-span-2">
|
<div class="border-gray-200 shadow shadow-primary-700 p-3 shadow-[0_0_4px_gray] col-span-2">
|
||||||
<f-text id="search_text" ref="searchTextField" v-model="searchText" class="col-span-2" label="Suchen …" size="sm" @keypress.enter.prevent="onSubmitFirstMemberResult"></f-text>
|
<f-text id="search_text" ref="searchInput" v-model="searchString" class="col-span-2" label="Suchen …" size="sm" @keypress.enter.prevent="onSubmitFirstMemberResult"></f-text>
|
||||||
<div class="mt-2 grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-2 col-span-2">
|
<div class="mt-2 grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-2 col-span-2">
|
||||||
<f-switch
|
<f-switch
|
||||||
v-for="member in results"
|
v-for="member in results.hits"
|
||||||
:id="`members-${member.id}`"
|
:id="`members-${member.id}`"
|
||||||
:key="member.id"
|
:key="member.id"
|
||||||
v-model="values.members"
|
v-model="values.members"
|
||||||
|
@ -26,17 +26,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button v-for="(compiler, index) in compilers" class="btn btn-primary mt-3 inline-block" @click.prevent="submit(compiler.class)" v-text="compiler.title"></button>
|
<button v-for="(compiler, index) in compilers" :key="index" class="btn btn-primary mt-3 inline-block" @click.prevent="submit(compiler.class)" v-text="compiler.title"></button>
|
||||||
</form>
|
</form>
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref, computed, inject} from 'vue';
|
import { ref, inject } from 'vue';
|
||||||
import useSearch from '../../composables/useSearch.js';
|
import useSearch from '../../composables/useSearch.js';
|
||||||
const axios = inject('axios');
|
const axios = inject('axios');
|
||||||
|
|
||||||
const {search} = useSearch();
|
const { searchString, results, clearSearch } = useSearch(['birthday IS NOT NULL', 'address IS NOT EMPTY']);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {},
|
data: {},
|
||||||
|
@ -44,13 +44,11 @@ const props = defineProps({
|
||||||
compilers: {},
|
compilers: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchRaw = ref('');
|
const searchInput = ref([]);
|
||||||
const results = ref([]);
|
|
||||||
const searchTextField = ref([]);
|
|
||||||
const values = ref({
|
const values = ref({
|
||||||
type: null,
|
type: null,
|
||||||
members: [],
|
members: [],
|
||||||
event_name: '',
|
eventName: '',
|
||||||
dateFrom: '',
|
dateFrom: '',
|
||||||
dateUntil: '',
|
dateUntil: '',
|
||||||
zipLocation: '',
|
zipLocation: '',
|
||||||
|
@ -58,15 +56,6 @@ const values = ref({
|
||||||
...props.data,
|
...props.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchText = computed({
|
|
||||||
get: () => searchRaw.value,
|
|
||||||
set: async (v) => {
|
|
||||||
searchRaw.value = v;
|
|
||||||
|
|
||||||
results.value = (await search(v, ['birthday IS NOT NULL', 'address IS NOT EMPTY'])).hits;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
async function submit(compiler) {
|
async function submit(compiler) {
|
||||||
values.value.type = compiler;
|
values.value.type = compiler;
|
||||||
await axios.post('/contribution-validate', values.value);
|
await axios.post('/contribution-validate', values.value);
|
||||||
|
@ -80,15 +69,15 @@ function onSubmitMemberResult(selected) {
|
||||||
values.value.members.push(selected.id);
|
values.value.members.push(selected.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchRaw.value = '';
|
clearSearch();
|
||||||
searchTextField.value.$el.querySelector('input').focus();
|
searchInput.value.$el.querySelector('input').focus();
|
||||||
}
|
}
|
||||||
function onSubmitFirstMemberResult() {
|
function onSubmitFirstMemberResult() {
|
||||||
if (results.value.length === 0) {
|
if (results.value.hits.length === 0) {
|
||||||
searchRaw.value = '';
|
clearSearch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmitMemberResult(results.value[0]);
|
onSubmitMemberResult(results.value.hits[0]);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -75,11 +75,11 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {useApiIndex} from '../../composables/useApiIndex.js';
|
import { useApiIndex } from '../../composables/useApiIndex.js';
|
||||||
import SettingLayout from '../setting/Layout.vue';
|
import SettingLayout from '../setting/Layout.vue';
|
||||||
|
|
||||||
const {meta, data, reload, create, edit, cancel, single, submit} = useApiIndex('/api/fileshare', 'fileshare');
|
const { meta, data, reload, create, edit, cancel, single, submit } = useApiIndex('/api/fileshare', 'fileshare');
|
||||||
|
|
||||||
function getType(type) {
|
function getType(type) {
|
||||||
if (!type) {
|
if (!type) {
|
||||||
|
|
|
@ -55,8 +55,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref, inject, computed} from 'vue';
|
import { ref, inject, computed } from 'vue';
|
||||||
const axios = inject('axios');
|
const axios = inject('axios');
|
||||||
const emit = defineEmits(['save']);
|
const emit = defineEmits(['save']);
|
||||||
|
|
||||||
|
@ -70,15 +70,15 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const comparatorOptions = ref([
|
const comparatorOptions = ref([
|
||||||
{id: 'isEqual', name: 'ist gleich', defaultValue: {DropdownField: null, RadioField: null, CheckboxField: false}},
|
{ id: 'isEqual', name: 'ist gleich', defaultValue: { DropdownField: null, RadioField: null, CheckboxField: false } },
|
||||||
{id: 'isNotEqual', name: 'ist ungleich', defaultValue: {DropdownField: null, RadioField: null, CheckboxField: false}},
|
{ id: 'isNotEqual', name: 'ist ungleich', defaultValue: { DropdownField: null, RadioField: null, CheckboxField: false } },
|
||||||
{id: 'isIn', name: 'ist in', defaultValue: {DropdownField: [], RadioField: [], CheckboxField: false}},
|
{ id: 'isIn', name: 'ist in', defaultValue: { DropdownField: [], RadioField: [], CheckboxField: false } },
|
||||||
{id: 'isNotIn', name: 'ist nicht in', defaultValue: {DropdownField: [], RadioField: [], CheckboxField: false}},
|
{ id: 'isNotIn', name: 'ist nicht in', defaultValue: { DropdownField: [], RadioField: [], CheckboxField: false } },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const modeOptions = ref([
|
const modeOptions = ref([
|
||||||
{id: 'all', name: 'alle Bedingungen müssen zutreffen'},
|
{ id: 'all', name: 'alle Bedingungen müssen zutreffen' },
|
||||||
{id: 'any', name: 'mindestens eine Bedingung muss zutreffen'},
|
{ id: 'any', name: 'mindestens eine Bedingung muss zutreffen' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const fields = computed(() => {
|
const fields = computed(() => {
|
||||||
|
@ -119,13 +119,13 @@ function getField(fieldName) {
|
||||||
|
|
||||||
function getOptions(fieldName) {
|
function getOptions(fieldName) {
|
||||||
return getField(fieldName).options.map((o) => {
|
return getField(fieldName).options.map((o) => {
|
||||||
return {id: o, name: o};
|
return { id: o, name: o };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldOptions = computed(() =>
|
const fieldOptions = computed(() =>
|
||||||
fields.value.map((field) => {
|
fields.value.map((field) => {
|
||||||
return {id: field.key, name: field.name};
|
return { id: field.key, name: field.name };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ async function save() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkIfDirty() {
|
async function checkIfDirty() {
|
||||||
const response = await axios.post(props.single.links.is_dirty, {config: props.single.config});
|
const response = await axios.post(props.single.links.is_dirty, { config: props.single.config });
|
||||||
|
|
||||||
locked.value = response.data.result;
|
locked.value = response.data.result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,16 +172,16 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref, inject, computed} from 'vue';
|
import { ref, inject, computed } from 'vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useInertiaApiIndex.js';
|
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||||
import FormBuilder from '../formtemplate/FormBuilder.vue';
|
import FormBuilder from '../formtemplate/FormBuilder.vue';
|
||||||
import Participants from './Participants.vue';
|
import Participants from './Participants.vue';
|
||||||
import Conditions from './Conditions.vue';
|
import Conditions from './Conditions.vue';
|
||||||
import {useToast} from 'vue-toastification';
|
import { useToast } from 'vue-toastification';
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
var {meta, data, reloadPage, create, single, edit, cancel, submit, remove, getFilter, setFilter} = useIndex(props.data, 'form');
|
var { meta, data, reloadPage, create, single, edit, cancel, submit, remove, getFilter, setFilter } = useIndex(props.data, 'form');
|
||||||
const axios = inject('axios');
|
const axios = inject('axios');
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
@ -191,8 +191,8 @@ const deleting = ref(null);
|
||||||
const showing = ref(null);
|
const showing = ref(null);
|
||||||
const fileSettingPopup = ref(null);
|
const fileSettingPopup = ref(null);
|
||||||
|
|
||||||
const tabs = [{title: 'Allgemeines'}, {title: 'Formular'}, {title: 'Bestätigungs-E-Mail'}, {title: 'Export'}];
|
const tabs = [{ title: 'Allgemeines' }, { title: 'Formular' }, { title: 'Bestätigungs-E-Mail' }, { title: 'Export' }];
|
||||||
const mailTabs = [{title: 'vor Daten'}, {title: 'nach Daten'}];
|
const mailTabs = [{ title: 'vor Daten' }, { title: 'nach Daten' }];
|
||||||
|
|
||||||
const allFields = computed(() => {
|
const allFields = computed(() => {
|
||||||
if (!single.value) {
|
if (!single.value) {
|
||||||
|
@ -202,7 +202,7 @@ const allFields = computed(() => {
|
||||||
var result = [];
|
var result = [];
|
||||||
single.value.config.sections.forEach((section) => {
|
single.value.config.sections.forEach((section) => {
|
||||||
section.fields.forEach((field) => {
|
section.fields.forEach((field) => {
|
||||||
result.push({id: field.key, name: field.name});
|
result.push({ id: field.key, name: field.name });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,43 +4,18 @@
|
||||||
<f-text id="search_string" v-model="searchString" label="Mitglied finden"></f-text>
|
<f-text id="search_string" v-model="searchString" label="Mitglied finden"></f-text>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="results !== null" class="mt-5 sm:mt-10 space-y-2">
|
<div v-if="results !== null" class="mt-5 sm:mt-10 space-y-2">
|
||||||
<a v-for="member in results.hits" :key="member.id" href="#" @click.prevent="emit('assign', member.id)">
|
<ui-search-result v-for="member in results.hits" :key="member.id" :member="member">
|
||||||
<div class="flex items-center justify-between hover:bg-sky-600/20 transition text-sky-300 px-3 sm:px-6 py-1 sm:py-3 rounded-lg">
|
<template #buttons>
|
||||||
<div class="flex space-x-2 items-center">
|
<button class="btn btn-primary btn-sm" @click.prevent="emit('assign', member.id)">Zuweisen</button>
|
||||||
<div class="w-5 sm:w-16 flex flex-none">
|
</template>
|
||||||
<ui-age-groups icon-class="w-4 h-4 sm:w-6 sm:h-6" class="flex-col sm:flex-row" :member="member"></ui-age-groups>
|
</ui-search-result>
|
||||||
</div>
|
|
||||||
<div class="flex items-baseline flex-col md:flex-row">
|
|
||||||
<span class="text-lg" v-text="member.fullname"></span>
|
|
||||||
<span class="ml-2 text-xs" v-text="member.group_name"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {computed, ref} from 'vue';
|
|
||||||
import useSearch from '../../composables/useSearch.js';
|
import useSearch from '../../composables/useSearch.js';
|
||||||
const emit = defineEmits(['assign']);
|
const emit = defineEmits(['assign']);
|
||||||
|
|
||||||
const {search} = useSearch();
|
const { searchString, results } = useSearch(null, { limit: 10 });
|
||||||
|
|
||||||
const realSearchString = ref('');
|
|
||||||
const results = ref(null);
|
|
||||||
|
|
||||||
const searchString = computed({
|
|
||||||
get: () => realSearchString.value,
|
|
||||||
set: async (v) => {
|
|
||||||
realSearchString.value = v;
|
|
||||||
|
|
||||||
if (!v.length) {
|
|
||||||
results.value = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
results.value = await search(v, [], {limit: 10});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -108,14 +108,14 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {watch, ref, computed} from 'vue';
|
import { watch, ref, computed } from 'vue';
|
||||||
import {useApiIndex} from '../../composables/useApiIndex.js';
|
import { useApiIndex } from '../../composables/useApiIndex.js';
|
||||||
import useTableToggle from '../../composables/useTableToggle.js';
|
import useTableToggle from '../../composables/useTableToggle.js';
|
||||||
import MemberAssign from './MemberAssign.vue';
|
import MemberAssign from './MemberAssign.vue';
|
||||||
|
|
||||||
const deleting = ref(null);
|
const deleting = ref(null);
|
||||||
const {isOpen, toggle, childrenOf, clearToggle} = useTableToggle({});
|
const { isOpen, toggle, childrenOf, clearToggle } = useTableToggle({});
|
||||||
|
|
||||||
const assigning = ref(null);
|
const assigning = ref(null);
|
||||||
|
|
||||||
|
@ -149,12 +149,12 @@ const groupParticipants = computed({
|
||||||
});
|
});
|
||||||
|
|
||||||
async function assign(memberId) {
|
async function assign(memberId) {
|
||||||
await axios.post(assigning.value.links.assign, {member_id: memberId});
|
await axios.post(assigning.value.links.assign, { member_id: memberId });
|
||||||
reload(false);
|
reload(false);
|
||||||
assigning.value = null;
|
assigning.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var {meta, data, reload, reloadPage, axios, remove, toFilterString, url, updateUrl} = useApiIndex(props.hasNamiField ? props.rootUrl : props.url, 'participant');
|
var { meta, data, reload, reloadPage, axios, remove, toFilterString, url, updateUrl } = useApiIndex(props.hasNamiField ? props.rootUrl : props.url, 'participant');
|
||||||
|
|
||||||
const activeColumns = computed(() => meta.value.columns.filter((c) => meta.value.form_meta.active_columns.includes(c.id)));
|
const activeColumns = computed(() => meta.value.columns.filter((c) => meta.value.form_meta.active_columns.includes(c.id)));
|
||||||
|
|
||||||
|
@ -186,19 +186,19 @@ watch(
|
||||||
filter: toFilterString(newValue),
|
filter: toFilterString(newValue),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{deep: true}
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const checkboxFilterOptions = ref([
|
const checkboxFilterOptions = ref([
|
||||||
{id: true, name: 'Ja'},
|
{ id: true, name: 'Ja' },
|
||||||
{id: false, name: 'Nein'},
|
{ id: false, name: 'Nein' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function dropdownFilterOptions(filter) {
|
function dropdownFilterOptions(filter) {
|
||||||
return [
|
return [
|
||||||
{id: null, name: 'keine Auswahl'},
|
{ id: null, name: 'keine Auswahl' },
|
||||||
...filter.options.map((f) => {
|
...filter.options.map((f) => {
|
||||||
return {id: f, name: f};
|
return { id: f, name: f };
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</ui-box>
|
</ui-box>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const emit = defineEmits(['close', 'submit']);
|
const emit = defineEmits(['close', 'submit']);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
></f-textarea>
|
></f-textarea>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
meta: {},
|
meta: {},
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import useElements from './useElements.js';
|
import useElements from './useElements.js';
|
||||||
const {addOption, setOption, removeOption} = useElements();
|
const { addOption, setOption, removeOption } = useElements();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
defineEmits(['update:modelValue']);
|
defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
></f-switch>
|
></f-switch>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
meta: {},
|
meta: {},
|
||||||
|
|
|
@ -71,9 +71,9 @@
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {watch, computed, ref} from 'vue';
|
import { watch, computed, ref } from 'vue';
|
||||||
import {snakeCase} from 'change-case';
|
import { snakeCase } from 'change-case';
|
||||||
import '!/adrema-form/dist/main.js';
|
import '!/adrema-form/dist/main.js';
|
||||||
import Asideform from './Asideform.vue';
|
import Asideform from './Asideform.vue';
|
||||||
import TextareaField from './TextareaField.vue';
|
import TextareaField from './TextareaField.vue';
|
||||||
|
@ -95,7 +95,7 @@ const active = ref(null);
|
||||||
async function onReorder() {
|
async function onReorder() {
|
||||||
var order = this.inner.map((f) => f.id);
|
var order = this.inner.map((f) => f.id);
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
This.inner = (await this.axios.patch(`/mediaupload/${this.parentName}/${this.parentId}/${this.collection}`, {order})).data;
|
This.inner = (await this.axios.patch(`/mediaupload/${this.parentName}/${this.parentId}/${this.collection}`, { order })).data;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ const fields = {
|
||||||
|
|
||||||
function editSection(sectionIndex) {
|
function editSection(sectionIndex) {
|
||||||
singleSection.value = {
|
singleSection.value = {
|
||||||
model: {...inner.value.sections[sectionIndex]},
|
model: { ...inner.value.sections[sectionIndex] },
|
||||||
index: sectionIndex,
|
index: sectionIndex,
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
};
|
};
|
||||||
|
@ -134,7 +134,7 @@ function editSection(sectionIndex) {
|
||||||
|
|
||||||
function startReordering(index) {
|
function startReordering(index) {
|
||||||
singleSection.value = {
|
singleSection.value = {
|
||||||
model: {...inner.value.sections[index]},
|
model: { ...inner.value.sections[index] },
|
||||||
index: index,
|
index: index,
|
||||||
mode: 'reorder',
|
mode: 'reorder',
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
></f-select>
|
></f-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {computed} from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
|
@ -57,7 +57,7 @@ const props = defineProps({
|
||||||
const fieldOptions = computed(() => {
|
const fieldOptions = computed(() => {
|
||||||
return props.payload.reduce((carry, section) => {
|
return props.payload.reduce((carry, section) => {
|
||||||
return section.fields.reduce((fcarry, field) => {
|
return section.fields.reduce((fcarry, field) => {
|
||||||
return field.type === 'GroupField' ? fcarry.concat({id: field.key, name: field.name}) : fcarry;
|
return field.type === 'GroupField' ? fcarry.concat({ id: field.key, name: field.name }) : fcarry;
|
||||||
}, carry);
|
}, carry);
|
||||||
}, []);
|
}, []);
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,15 +58,15 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref} from 'vue';
|
import { ref } from 'vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useInertiaApiIndex.js';
|
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||||
import FormBuilder from './FormBuilder.vue';
|
import FormBuilder from './FormBuilder.vue';
|
||||||
|
|
||||||
const deleting = ref(null);
|
const deleting = ref(null);
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
var {meta, data, reloadPage, create, remove, single, edit, cancel, submit} = useIndex(props.data, 'invoice');
|
var { meta, data, reloadPage, create, remove, single, edit, cancel, submit } = useIndex(props.data, 'invoice');
|
||||||
|
|
||||||
function innerSubmit(payload) {
|
function innerSubmit(payload) {
|
||||||
single.value = payload;
|
single.value = payload;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<f-text id="max" :model-value="modelValue.max" label="maximaler Wert" size="sm" type="number" @update:modelValue="$emit('update:modelValue', {...modelValue, max: parse($event)})"></f-text>
|
<f-text id="max" :model-value="modelValue.max" label="maximaler Wert" size="sm" type="number" @update:modelValue="$emit('update:modelValue', {...modelValue, max: parse($event)})"></f-text>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
meta: {},
|
meta: {},
|
||||||
|
|
|
@ -38,9 +38,9 @@
|
||||||
></f-switch>
|
></f-switch>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import useElements from './useElements.js';
|
import useElements from './useElements.js';
|
||||||
const {addOption, setOption, removeOption} = useElements();
|
const { addOption, setOption, removeOption } = useElements();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
></f-switch>
|
></f-switch>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
meta: {},
|
meta: {},
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
></f-switch>
|
></f-switch>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {},
|
modelValue: {},
|
||||||
meta: {},
|
meta: {},
|
||||||
|
|
|
@ -92,14 +92,14 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref} from 'vue';
|
import { ref } from 'vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useInertiaApiIndex.js';
|
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||||
import useTableToggle from '../../composables/useTableToggle.js';
|
import useTableToggle from '../../composables/useTableToggle.js';
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
var {axios, meta, data} = useIndex(props.data, 'invoice');
|
var { axios, meta, data } = useIndex(props.data, 'invoice');
|
||||||
const {isOpen, toggle, childrenOf} = useTableToggle({null: data.value});
|
const { isOpen, toggle, childrenOf } = useTableToggle({ null: data.value });
|
||||||
|
|
||||||
var editing = ref(null);
|
var editing = ref(null);
|
||||||
|
|
||||||
|
|
|
@ -124,14 +124,14 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref} from 'vue';
|
import { ref } from 'vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useInertiaApiIndex.js';
|
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
var {axios, meta, data, reloadPage, create, single, edit, cancel, submit, remove, getFilter, setFilter} = useIndex(props.data, 'invoice');
|
var { axios, meta, data, reloadPage, create, single, edit, cancel, submit, remove, getFilter, setFilter } = useIndex(props.data, 'invoice');
|
||||||
const massstore = ref(null);
|
const massstore = ref(null);
|
||||||
const deleting = ref(null);
|
const deleting = ref(null);
|
||||||
const forMember = ref({member_id: null, subscription_id: null, year: null});
|
const forMember = ref({ member_id: null, subscription_id: null, year: null });
|
||||||
|
|
||||||
async function saveForMember() {
|
async function saveForMember() {
|
||||||
single.value = (await axios.post(meta.value.links.newInvoiceAttributes, forMember.value)).data;
|
single.value = (await axios.post(meta.value.links.newInvoiceAttributes, forMember.value)).data;
|
||||||
|
|
|
@ -74,9 +74,9 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {ref, inject, defineProps} from 'vue';
|
import { ref, inject, defineProps } from 'vue';
|
||||||
import {useIndex} from '../../composables/useIndex.js';
|
import { useIndex } from '../../composables/useIndex.js';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
|
@ -85,13 +85,13 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
meta: {
|
meta: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => { },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const {router} = useIndex({data: [], meta: {}}, 'maildispatcher');
|
const { router } = useIndex({ data: [], meta: {} }, 'maildispatcher');
|
||||||
|
|
||||||
const model = ref(props.data === undefined ? {...props.meta.default_model} : {...props.data});
|
const model = ref(props.data === undefined ? { ...props.meta.default_model } : { ...props.data });
|
||||||
const members = ref(null);
|
const members = ref(null);
|
||||||
const axios = inject('axios');
|
const axios = inject('axios');
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,12 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import {indexProps, useIndex} from '../../composables/useInertiaApiIndex.js';
|
import { indexProps, useIndex } from '../../composables/useInertiaApiIndex.js';
|
||||||
import SettingLayout from '../setting/Layout.vue';
|
import SettingLayout from '../setting/Layout.vue';
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
const {meta, data, create, edit, cancel, single, submit} = useIndex(props.data, 'mailgateway');
|
const { meta, data, create, edit, cancel, single, submit } = useIndex(props.data, 'mailgateway');
|
||||||
|
|
||||||
function getType(type) {
|
function getType(type) {
|
||||||
return meta.value.types.find((t) => t.id === type);
|
return meta.value.types.find((t) => t.id === type);
|
||||||
|
|
|
@ -2,17 +2,14 @@
|
||||||
<div class="sidebar flex flex-col group is-bright">
|
<div class="sidebar flex flex-col group is-bright">
|
||||||
<page-header title="Ausbildungen" @close="$emit('close')">
|
<page-header title="Ausbildungen" @close="$emit('close')">
|
||||||
<template #toolbar>
|
<template #toolbar>
|
||||||
<page-toolbar-button v-if="single === null" color="primary" icon="plus" @click.prevent="create">Neue
|
<page-toolbar-button v-if="single === null" color="primary" icon="plus" @click.prevent="create">Neue Ausbildung</page-toolbar-button>
|
||||||
Ausbildung</page-toolbar-button>
|
<page-toolbar-button v-if="single !== null" color="primary" icon="undo" @click.prevent="cancel">Zurück</page-toolbar-button>
|
||||||
<page-toolbar-button v-if="single !== null" color="primary" icon="undo"
|
|
||||||
@click.prevent="cancel">Zurück</page-toolbar-button>
|
|
||||||
</template>
|
</template>
|
||||||
</page-header>
|
</page-header>
|
||||||
|
|
||||||
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
|
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
|
||||||
<f-text id="completed_at" v-model="single.completed_at" type="date" label="Datum" required></f-text>
|
<f-text id="completed_at" v-model="single.completed_at" type="date" label="Datum" required></f-text>
|
||||||
<f-select id="course_id" v-model="single.course_id" name="course_id" :options="meta.courses" label="Baustein"
|
<f-select id="course_id" v-model="single.course_id" name="course_id" :options="meta.courses" label="Baustein" required></f-select>
|
||||||
required></f-select>
|
|
||||||
<f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required></f-text>
|
<f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required></f-text>
|
||||||
<f-text id="organizer" v-model="single.organizer" label="Veranstalter" required></f-text>
|
<f-text id="organizer" v-model="single.organizer" label="Veranstalter" required></f-text>
|
||||||
<button type="submit" class="btn btn-primary">Absenden</button>
|
<button type="submit" class="btn btn-primary">Absenden</button>
|
||||||
|
@ -34,10 +31,8 @@
|
||||||
<td v-text="course.organizer"></td>
|
<td v-text="course.organizer"></td>
|
||||||
<td v-text="course.completed_at_human"></td>
|
<td v-text="course.completed_at_human"></td>
|
||||||
<td class="flex">
|
<td class="flex">
|
||||||
<a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(course)"><ui-sprite
|
<a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(course)"><ui-sprite src="pencil"></ui-sprite></a>
|
||||||
src="pencil"></ui-sprite></a>
|
<a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(course)"><ui-sprite src="trash"></ui-sprite></a>
|
||||||
<a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(course)"><ui-sprite
|
|
||||||
src="trash"></ui-sprite></a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -45,7 +40,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
defineEmits(['close']);
|
defineEmits(['close']);
|
||||||
import { useApiIndex } from '../../composables/useApiIndex.js';
|
import { useApiIndex } from '../../composables/useApiIndex.js';
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
defineEmits(['close']);
|
defineEmits(['close']);
|
||||||
import { useApiIndex } from '../../composables/useApiIndex.js';
|
import { useApiIndex } from '../../composables/useApiIndex.js';
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<page-header title="Mitgliedschaften" @close="$emit('close')">
|
<page-header title="Mitgliedschaften" @close="$emit('close')">
|
||||||
<template #toolbar>
|
<template #toolbar>
|
||||||
<page-toolbar-button v-if="single === null" color="primary" icon="plus" @click.prevent="create">Neue
|
<page-toolbar-button v-if="single === null" color="primary" icon="plus" @click.prevent="create">Neue Mitgliedschaft</page-toolbar-button>
|
||||||
Mitgliedschaft</page-toolbar-button>
|
<page-toolbar-button v-if="single !== null" color="primary" icon="undo" @click.prevent="single = null">Zurück</page-toolbar-button>
|
||||||
<page-toolbar-button v-if="single !== null" color="primary" icon="undo"
|
|
||||||
@click.prevent="single = null">Zurück</page-toolbar-button>
|
|
||||||
</template>
|
</template>
|
||||||
</page-header>
|
</page-header>
|
||||||
|
|
||||||
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
|
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
|
||||||
<f-select id="group_id" v-model="single.group_id" name="group_id" :options="meta.groups" label="Gruppierung"
|
<f-select id="group_id" v-model="single.group_id" name="group_id" :options="meta.groups" label="Gruppierung" required></f-select>
|
||||||
required></f-select>
|
<f-select id="activity_id" v-model="single.activity_id" name="activity_id" :options="meta.activities" label="Tätigkeit" required></f-select>
|
||||||
<f-select id="activity_id" v-model="single.activity_id" name="activity_id" :options="meta.activities"
|
<f-select
|
||||||
label="Tätigkeit" required></f-select>
|
v-if="single.activity_id"
|
||||||
<f-select v-if="single.activity_id" id="subactivity_id" :model-value="single.subactivity_id" name="subactivity_id"
|
id="subactivity_id"
|
||||||
:options="meta.subactivities[single.activity_id]" label="Untertätigkeit"
|
:model-value="single.subactivity_id"
|
||||||
@update:modelValue="setSubactivityId(single, $event)"></f-select>
|
name="subactivity_id"
|
||||||
<f-switch v-if="displayPromisedAt" id="has_promise" :model-value="single.promised_at !== null"
|
:options="meta.subactivities[single.activity_id]"
|
||||||
label="Hat Versprechen" @update:modelValue="setPromisedAtSwitch(single, $event)"></f-switch>
|
label="Untertätigkeit"
|
||||||
<f-text v-show="displayPromisedAt && single.promised_at !== null" id="promised_at" v-model="single.promised_at"
|
@update:modelValue="setSubactivityId(single, $event)"
|
||||||
type="date" label="Versprechensdatum" size="sm"></f-text>
|
></f-select>
|
||||||
|
<f-switch v-if="displayPromisedAt" id="has_promise" :model-value="single.promised_at !== null" label="Hat Versprechen" @update:modelValue="setPromisedAtSwitch(single, $event)"></f-switch>
|
||||||
|
<f-text v-show="displayPromisedAt && single.promised_at !== null" id="promised_at" v-model="single.promised_at" type="date" label="Versprechensdatum" size="sm"></f-text>
|
||||||
<button type="submit" class="btn btn-primary">Absenden</button>
|
<button type="submit" class="btn btn-primary">Absenden</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -39,17 +39,15 @@
|
||||||
<td v-text="membership.human_date"></td>
|
<td v-text="membership.human_date"></td>
|
||||||
<td><ui-boolean-display :value="membership.is_active" dark></ui-boolean-display></td>
|
<td><ui-boolean-display :value="membership.is_active" dark></ui-boolean-display></td>
|
||||||
<td class="flex space-x-1">
|
<td class="flex space-x-1">
|
||||||
<a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(membership)"><ui-sprite
|
<a href="#" class="inline-flex btn btn-warning btn-sm" @click.prevent="edit(membership)"><ui-sprite src="pencil"></ui-sprite></a>
|
||||||
src="pencil"></ui-sprite></a>
|
<a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(membership)"><ui-sprite src="trash"></ui-sprite></a>
|
||||||
<a href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="remove(membership)"><ui-sprite
|
|
||||||
src="trash"></ui-sprite></a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
|
|
@ -132,21 +132,21 @@
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
import MemberInvoicePositions from './MemberInvoicePositions.vue';
|
import MemberInvoicePositions from './MemberInvoicePositions.vue';
|
||||||
import MemberMemberships from './MemberMemberships.vue';
|
import MemberMemberships from './MemberMemberships.vue';
|
||||||
import MemberCourses from './MemberCourses.vue';
|
import MemberCourses from './MemberCourses.vue';
|
||||||
import Tags from './Tags.vue';
|
import Tags from './Tags.vue';
|
||||||
import Actions from './index/Actions.vue';
|
import Actions from './index/Actions.vue';
|
||||||
import {indexProps, useIndex} from '../../composables/useIndex.js';
|
import { indexProps, useIndex } from '../../composables/useIndex.js';
|
||||||
import {ref, defineProps} from 'vue';
|
import { ref, defineProps } from 'vue';
|
||||||
|
|
||||||
const single = ref(null);
|
const single = ref(null);
|
||||||
const deleting = ref(null);
|
const deleting = ref(null);
|
||||||
const membershipFilters = ref(null);
|
const membershipFilters = ref(null);
|
||||||
|
|
||||||
const props = defineProps(indexProps);
|
const props = defineProps(indexProps);
|
||||||
var {router, data, meta, getFilter, setFilter, filterString, reloadPage} = useIndex(props.data, 'member');
|
var { router, data, meta, getFilter, setFilter, filterString, reloadPage } = useIndex(props.data, 'member');
|
||||||
|
|
||||||
function exportMembers() {
|
function exportMembers() {
|
||||||
window.open(`/member-export?filter=${filterString.value}`);
|
window.open(`/member-export?filter=${filterString.value}`);
|
||||||
|
@ -154,7 +154,7 @@ function exportMembers() {
|
||||||
|
|
||||||
async function remove(member) {
|
async function remove(member) {
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
deleting.value = {resolve, reject, member};
|
deleting.value = { resolve, reject, member };
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
router.delete(`/member/${member.id}`);
|
router.delete(`/member/${member.id}`);
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex space-x-1">
|
<div class="flex space-x-1">
|
||||||
<i-link v-tooltip="`Details`" :href="member.links.show" class="inline-flex btn btn-primary btn-sm"><ui-sprite
|
<i-link v-tooltip="`Details`" :href="member.links.show" class="inline-flex btn btn-primary btn-sm"><ui-sprite src="eye"></ui-sprite></i-link>
|
||||||
src="eye"></ui-sprite></i-link>
|
<i-link v-tooltip="`Bearbeiten`" :href="member.links.edit" class="inline-flex btn btn-warning btn-sm"><ui-sprite src="pencil"></ui-sprite></i-link>
|
||||||
<i-link v-tooltip="`Bearbeiten`" :href="member.links.edit" class="inline-flex btn btn-warning btn-sm"><ui-sprite
|
<a v-show="hasModule('bill')" v-tooltip="`Zahlungen`" href="#" class="inline-flex btn btn-info btn-sm" @click.prevent="$emit('sidebar', 'invoicePosition')"
|
||||||
src="pencil"></ui-sprite></i-link>
|
><ui-sprite src="money"></ui-sprite
|
||||||
<a v-show="hasModule('bill')" v-tooltip="`Zahlungen`" href="#" class="inline-flex btn btn-info btn-sm"
|
></a>
|
||||||
@click.prevent="$emit('sidebar', 'invoicePosition')"><ui-sprite src="money"></ui-sprite></a>
|
<a v-show="hasModule('courses')" v-tooltip="`Ausbildungen`" href="#" class="inline-flex btn btn-info btn-sm" @click.prevent="$emit('sidebar', 'courses')"
|
||||||
<a v-show="hasModule('courses')" v-tooltip="`Ausbildungen`" href="#" class="inline-flex btn btn-info btn-sm"
|
><ui-sprite src="course"></ui-sprite
|
||||||
@click.prevent="$emit('sidebar', 'courses')"><ui-sprite src="course"></ui-sprite></a>
|
></a>
|
||||||
<a v-tooltip="`Mitgliedschaften`" href="#" class="inline-flex btn btn-info btn-sm"
|
<a v-tooltip="`Mitgliedschaften`" href="#" class="inline-flex btn btn-info btn-sm" @click.prevent="$emit('sidebar', 'membership')"><ui-sprite src="user"></ui-sprite></a>
|
||||||
@click.prevent="$emit('sidebar', 'membership')"><ui-sprite src="user"></ui-sprite></a>
|
<a v-show="member.efz_link" v-tooltip="`EFZ Formular`" :href="member.efz_link" class="inline-flex btn btn-info btn-sm"><ui-sprite src="report"></ui-sprite></a>
|
||||||
<a v-show="member.efz_link" v-tooltip="`EFZ Formular`" :href="member.efz_link"
|
<a v-tooltip="`Entfernen`" href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="$emit('remove')"><ui-sprite src="trash"></ui-sprite></a>
|
||||||
class="inline-flex btn btn-info btn-sm"><ui-sprite src="report"></ui-sprite></a>
|
|
||||||
<a v-tooltip="`Entfernen`" href="#" class="inline-flex btn btn-danger btn-sm"
|
|
||||||
@click.prevent="$emit('remove')"><ui-sprite src="trash"></ui-sprite></a>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="js" setup>
|
||||||
defineProps({
|
defineProps({
|
||||||
member: {
|
member: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
Loading…
Reference in New Issue