Add global save button

This commit is contained in:
philipp lang 2022-12-04 23:40:35 +01:00
parent b1c8fb6dd1
commit f2d4ad5674
11 changed files with 107 additions and 54 deletions

15
package-lock.json generated
View File

@ -9,6 +9,7 @@
"@inertiajs/inertia-vue": "^0.8.0",
"lodash": "^4.17.21",
"merge": "^2.1.1",
"portal-vue": "^2.1.7",
"postcss-import": "^14.0.1",
"query-string": "^7.0.0",
"svg-sprite": "^2.0.2",
@ -7791,6 +7792,14 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/portal-vue": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz",
"integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==",
"peerDependencies": {
"vue": "^2.5.18"
}
},
"node_modules/portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
@ -16790,6 +16799,12 @@
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portal-vue": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz",
"integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==",
"requires": {}
},
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",

View File

@ -27,6 +27,7 @@
"@inertiajs/inertia-vue": "^0.8.0",
"lodash": "^4.17.21",
"merge": "^2.1.1",
"portal-vue": "^2.1.7",
"postcss-import": "^14.0.1",
"query-string": "^7.0.0",
"svg-sprite": "^2.0.2",

View File

@ -0,0 +1 @@
<svg viewBox="0 0 60 60" width="480" height="480" xmlns="http://www.w3.org/2000/svg"><path d="m59.707 8.293-8-8A1 1 0 0 0 51 0H5a5.006 5.006 0 0 0-5 5v50a5.006 5.006 0 0 0 5 5h50a5.006 5.006 0 0 0 5-5V9a1 1 0 0 0-.293-.707ZM46 2v16a1 1 0 0 1-1 1H15a1 1 0 0 1-1-1V2ZM8 58V33a3 3 0 0 1 3-3h38a3 3 0 0 1 3 3v25zm50-3a3 3 0 0 1-3 3h-1V33a5.006 5.006 0 0 0-5-5H11a5.006 5.006 0 0 0-5 5v25H5a3 3 0 0 1-3-3V5a3 3 0 0 1 3-3h7v16a3 3 0 0 0 3 3h30a3 3 0 0 0 3-3V2h2.586L58 9.414Z"/><path d="M37 17h6a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1zm1-11h4v9h-4zM45 43H15a1 1 0 0 0 0 2h30a1 1 0 0 0 0-2zM45 37H15a1 1 0 0 0 0 2h30a1 1 0 0 0 0-2zM45 49H15a1 1 0 0 0 0 2h30a1 1 0 0 0 0-2z"/></svg>

After

Width:  |  Height:  |  Size: 699 B

15
resources/js/app.js vendored
View File

@ -2,10 +2,6 @@ import Vue from 'vue';
import {App as InertiaApp, plugin, Link as ILink} from '@inertiajs/inertia-vue';
import SvgSprite from './components/SvgSprite.js';
import FText from './components/FText.vue';
import FSwitch from './components/FSwitch.vue';
import FSelect from './components/FSelect.vue';
import FTextarea from './components/FTextarea.vue';
import VPages from './components/VPages.vue';
import VLabel from './components/VLabel.vue';
import VBool from './components/VBool.vue';
@ -14,19 +10,22 @@ import Heading from './components/Heading.vue';
import AppLayout from './layouts/AppLayout.vue';
import VTooltip from 'v-tooltip';
import hasModule from './mixins/hasModule.js';
import PortalVue from 'portal-vue';
Vue.use(plugin);
Vue.use(PortalVue);
Vue.use(VTooltip);
Vue.component('f-text', FText);
Vue.component('f-switch', FSwitch);
Vue.component('f-select', FSelect);
Vue.component('f-textarea', FTextarea);
Vue.component('f-text', () => import(/* webpackChunkName: "form" */ './components/FText'));
Vue.component('f-switch', () => import(/* webpackChunkName: "form" */ './components/FSwitch'));
Vue.component('f-select', () => import(/* webpackChunkName: "form" */ './components/FSelect'));
Vue.component('f-textarea', () => import(/* webpackChunkName: "form" */ './components/FTextarea'));
Vue.component('SvgSprite', SvgSprite);
Vue.component('VPages', VPages);
Vue.component('v-bool', VBool);
Vue.component('v-label', VLabel);
Vue.component('box', Box);
Vue.component('heading', Heading);
Vue.component('save-button', () => import(/* webpackChunkName: "form" */ './components/SaveButton'));
const el = document.getElementById('app');

View File

@ -0,0 +1,22 @@
<template>
<portal to="toolbar-right">
<button
:form="form"
type="submit"
class="flex items-center transition-all justify-center w-8 h-8 bg-primary-700 hover:bg-primary-600 rounded"
v-tooltip="`speichern`"
>
<svg-sprite class="w-4 h-4 text-white" src="save"></svg-sprite>
</button>
</portal>
</template>
<script>
export default {
props: {
form: {
required: true,
},
},
};
</script>

View File

@ -2,11 +2,22 @@
<div class="h-16 px-6 flex justify-between items-center border-b border-solid border-gray-500">
<div class="flex items-center">
<span class="mr-1 text-xl font-semibold leading-none text-white" v-html="title"></span>
<a v-for="link, index in links.filter(link => link.icon === undefined)" :key="index" @click.prevent="$emit(link.event)" href="#" class="btn label btn-primary-light">
<a
v-for="(link, index) in links.filter((link) => link.icon === undefined)"
:key="index"
@click.prevent="$emit(link.event)"
href="#"
class="btn label btn-primary-light"
>
<span v-if="link.label" v-text="link.label"></span>
<svg-sprite v-if="link.icon" :src="link.icon"></svg-sprite>
</a>
<a v-for="link, index in links.filter(link => link.icon !== undefined)" :key="index" :href="link.href" class="btn label icon btn-primary-light ml-1">
<a
v-for="(link, index) in links.filter((link) => link.icon !== undefined)"
:key="index"
:href="link.href"
class="btn label icon btn-primary-light ml-1"
>
<span v-if="link.label" v-text="link.label"></span>
<svg-sprite v-if="link.icon" :src="link.icon"></svg-sprite>
</a>
@ -23,11 +34,15 @@
export default {
props: {
links: {
default: function() { return []; }
default: function () {
return [];
},
},
title: {
default: function() { return ''; }
}
}
default: function () {
return '';
},
},
},
};
</script>

View File

@ -36,36 +36,36 @@
class="grow bg-gray-900 flex flex-col transition-all"
:class="{'ml-56': menuVisible, 'ml-0': !menuVisible}"
>
<div class="h-16 px-6 flex justify-between items-center border-b border-gray-600">
<div class="flex space-x-3 items-center">
<a href="#" @click.prevent="menuOverflowVisible = !menuOverflowVisible" class="lg:hidden">
<svg-sprite src="menu" class="text-gray-100 w-5 h-5"></svg-sprite>
</a>
<span
class="text-sm md:text-xl font-semibold text-white leading-none"
v-html="$page.props.title"
></span>
<div class="flex ml-4">
<i-link
v-for="(link, index) in filterMenu"
:key="index"
:href="link.href"
class="btn label mr-2"
:class="`btn-${link.color}`"
v-tooltip="tooltipsVisible ? link.label : ''"
>
<svg-sprite v-show="link.icon" class="w-3 h-3 xl:mr-2" :src="link.icon"></svg-sprite>
<span class="hidden xl:inline" v-text="link.label"></span>
</i-link>
</div>
<div class="h-16 px-6 flex items-center space-x-3 border-b border-gray-600">
<a href="#" @click.prevent="menuOverflowVisible = !menuOverflowVisible" class="lg:hidden">
<svg-sprite src="menu" class="text-gray-100 w-5 h-5"></svg-sprite>
</a>
<span
class="text-sm md:text-xl font-semibold text-white leading-none"
v-html="$page.props.title"
></span>
<i-link
v-for="(link, index) in filterMenu"
:key="index"
:href="link.href"
class="btn label mr-2"
:class="`btn-${link.color}`"
v-tooltip="tooltipsVisible ? link.label : ''"
>
<svg-sprite v-show="link.icon" class="w-3 h-3 xl:mr-2" :src="link.icon"></svg-sprite>
<span class="hidden xl:inline" v-text="link.label"></span>
</i-link>
<div class="flex grow justify-between">
<portal-target name="toolbar-left"> </portal-target>
<portal-target name="toolbar-right"> </portal-target>
</div>
<label
for="search"
:class="{'opacity-0 sm:opacity-100': !searchVisible, 'opacity-100': searchVisible}"
class="absolute left-14 sm:static transition-all"
class="absolute left-10 sm:static transition-all"
>
<input
class="shadow-lg bg-gray-800 rounded-lg py-2 px-3 text-gray-300 hover:bg-gray-700 focus:bg-gray-700 placeholder-gray-400"
class="shadow-lg bg-gray-800 rounded-lg py-2 px-3 h-10 text-gray-300 hover:bg-gray-700 focus:bg-gray-700 placeholder-gray-400"
placeholder="Suchen…"
name="search"
v-model="isearch"

View File

@ -1,5 +1,6 @@
<template>
<form class="flex grow relative" @submit.prevent="submit">
<form class="flex grow relative" id="memberedit" @submit.prevent="submit">
<save-button form="memberedit"></save-button>
<popup heading="Ein Konflikt ist aufgetreten" v-if="conflict === true">
<div>
<p class="mt-4">
@ -164,9 +165,6 @@
required
></f-select>
</div>
<div>
<button type="submit" class="mt-3 btn btn-sm inline-block btn-primary">Speichern</button>
</div>
</div>
</box>
<box heading="Prävention">

View File

@ -1,5 +1,10 @@
<template>
<form class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit">
<form
id="billsettingform"
class="grow p-6 grid grid-cols-2 gap-3 items-start content-start"
@submit.prevent="submit"
>
<save-button form="billsettingform"></save-button>
<f-text
label="Absender"
hint="Absender-Name in Kurzform, i.d.R. der kurze Stammesname"
@ -26,10 +31,6 @@
<f-text label="Webseite" v-model="inner.website" name="website" id="website"></f-text>
<f-text label="IBAN" v-model="inner.iban" name="iban" id="iban"></f-text>
<f-text label="BIC" v-model="inner.bic" name="bic" id="bic"></f-text>
<div>
<button type="submit" class="mt-3 btn block btn-primary">Speichern</button>
</div>
</form>
</template>

View File

@ -1,5 +1,10 @@
<template>
<form class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit">
<form
id="mailmansettingform"
class="grow p-6 grid grid-cols-2 gap-3 items-start content-start"
@submit.prevent="submit"
>
<save-button form="mailmansettingform"></save-button>
<div class="col-span-full text-gray-100 mb-3">
<p class="text-sm">
Scoutrobot kann automatisch Mailinglisten erstellen, wenn es mit einem existierenden
@ -49,9 +54,6 @@
:options="lists"
></f-select>
<div></div>
<div>
<button type="submit" class="mt-3 btn block btn-primary">Speichern</button>
</div>
</form>
</template>

View File

@ -1,5 +1,6 @@
<template>
<form class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<form id="subedit" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<save-button form="subedit"></save-button>
<f-text id="name" v-model="inner.name" label="Name" required></f-text>
<f-select
id="fee_id"
@ -10,8 +11,6 @@
required
></f-select>
<f-text id="amount" v-model="inner.amount" label="Interner Beitrag" mode="area" required></f-text>
<button type="submit" class="btn btn-primary">Absenden</button>
</form>
</template>