release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
70 changed files with 344 additions and 150 deletions
Showing only changes of commit 3eea079871 - Show all commits

View File

@ -10,12 +10,11 @@
"lint": "eslint --ext .js,.ts,.vue ./src"
},
"dependencies": {
"@quasar/extras": "^1.9.19",
"axios": "^0.21.1",
"cordova": "^10.0.0",
"core-js": "^3.9.1",
"pinia": "^2.0.0-alpha.7",
"quasar": "^2.0.0-beta.9"
"quasar": "^2.0.0-beta.11"
},
"prettier": {
"singleQuote": true,
@ -24,7 +23,8 @@
"arrowParens": "always"
},
"devDependencies": {
"@quasar/app": "^3.0.0-beta.9",
"@quasar/app": "^3.0.0-beta.10",
"@quasar/extras": "^1.10.0",
"@quasar/quasar-app-extension-qcalendar": "file:deps/quasar-ui-qcalendar/app-extension",
"@types/node": "^12.20.6",
"@types/webpack": "^4.41.26",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -313,7 +313,7 @@ async function getBackend() {
*/
export default boot(async ({ router, app }) => {
const backend = await getBackend();
if (!backend) {
if (backend === null) {
void router.push({ name: 'error' });
return;
}

View File

@ -0,0 +1,45 @@
<template>
<q-card bordered class="row q-ma-xs q-pa-xs" style="position: relative">
<div class="col-12 text-weight-light">{{ dateString }}</div>
<div class="col-12">{{ modelValue.text }}</div>
<q-btn
round
dense
icon="close"
size="sm"
color="negative"
class="q-ma-xs"
style="position: absolute; top: 0; right: 0"
@click="remove"
/>
</q-card>
</template>
<script lang="ts">
import { defineComponent, PropType, computed } from 'vue';
import { formatDateTime } from 'src/utils/datetime';
export default defineComponent({
name: 'Notification',
props: {
modelValue: {
required: true,
type: Object as PropType<FG.Notification>,
},
},
emits: {
remove: (id: number) => !!id,
},
setup(props, { emit }) {
const dateString = computed(() => formatDateTime(props.modelValue.time, true, true));
function remove() {
emit('remove', props.modelValue.id);
}
return { dateString, remove };
},
});
</script>
<style scoped></style>

View File

@ -1,11 +1,10 @@
declare namespace FG {
interface Session {
expires: Date;
token: string;
lifetime: number;
browser: string;
platform: string;
userid: string;
interface Notification {
id: number;
plugin: string;
text: string;
data?: unknown;
time: Date;
}
interface User {
userid: string;
@ -18,6 +17,14 @@ declare namespace FG {
permissions?: Array<string>;
avatar_url?: string;
}
interface Session {
expires: Date;
token: string;
lifetime: number;
browser: string;
platform: string;
userid: string;
}
type Permission = string;
interface Role {
id: number;
@ -69,6 +76,7 @@ declare namespace FG {
}
interface Service {
userid: string;
is_backup: boolean;
value: number;
}
interface Drink {
@ -77,8 +85,8 @@ declare namespace FG {
package_size?: number;
name: string;
volume?: number;
cost_price_pro_volume?: number;
cost_price_package_netto?: number;
cost_per_volume?: number;
cost_per_package?: number;
tags?: Array<Tag>;
type?: DrinkType;
volumes: Array<DrinkPriceVolume>;
@ -88,7 +96,7 @@ declare namespace FG {
interface DrinkIngredient {
id: number;
volume: number;
drink_ingredient_id: number;
ingredient_id: number;
}
interface DrinkPrice {
id: number;

View File

@ -21,6 +21,25 @@
</q-toolbar-title>
<!-- Hier kommen die Shortlinks hin -->
<q-btn icon="message" flat dense
><q-badge color="negative" floating>{{ notifications.length }}</q-badge>
<q-menu style="max-height: 400px; overflow: auto">
<q-btn
v-if="noPermission"
label="Benachrichtigungen erlauben"
@click="requestPermission"
/>
<template v-if="notifications.length > 0">
<Notification
v-for="(notification, index) in notifications"
:key="index"
:model-value="notification"
@remove="remove"
/>
</template>
<div v-else class="q-pa-sm">Keine neuen Benachrichtigungen</div>
</q-menu>
</q-btn>
<shortcut-link
v-for="(shortcut, index) in shortcuts"
:key="'shortcut' + index"
@ -84,8 +103,9 @@
<script lang="ts">
import EssentialLink from 'src/components/navigation/EssentialLink.vue';
import ShortcutLink from 'src/components/navigation/ShortcutLink.vue';
import Notification from 'src/components/Notification.vue';
import { Screen } from 'quasar';
import { defineComponent, ref, inject, computed } from 'vue';
import { defineComponent, ref, inject, computed, onBeforeMount } from 'vue';
import { useMainStore } from 'src/store';
import { FG_Plugin } from 'src/plugins';
import { useRouter } from 'vue-router';
@ -100,7 +120,7 @@ const essentials: FG_Plugin.MenuLink[] = [
export default defineComponent({
name: 'MainLayout',
components: { EssentialLink, ShortcutLink },
components: { EssentialLink, ShortcutLink, Notification },
setup() {
const router = useRouter();
const mainStore = useMainStore();
@ -108,6 +128,16 @@ export default defineComponent({
const leftDrawer = ref(false);
const shortcuts = flaschengeist?.shortcuts;
const mainLinks = flaschengeist?.menuLinks;
const notifications = computed(() => mainStore.notifications.slice().reverse());
const noPermission = ref(window.Notification.permission !== 'granted');
function requestPermission() {
void window.Notification.requestPermission().then(
(p) => (noPermission.value = p !== 'granted')
);
}
onBeforeMount(() => window.setInterval(() => void mainStore.loadNotifications(), 30000));
const leftDrawerOpen = computed({
get: () => (leftDrawer.value || Screen.gt.sm ? true : false),
@ -131,6 +161,10 @@ export default defineComponent({
void mainStore.logout();
}
async function remove(id: number) {
await mainStore.removeNotification(id);
}
return {
essentials,
leftDrawerOpen,
@ -138,6 +172,10 @@ export default defineComponent({
leftDrawerClicker,
logout,
mainLinks,
notifications,
noPermission,
remove,
requestPermission,
shortcuts,
subLinks,
};

View File

@ -181,7 +181,7 @@ export default defineComponent({
id: -1,
drink_ingredient: {
id: -1,
drink_ingredient_id: newIngredient.value.id,
ingredient_id: newIngredient.value.id,
volume: newIngredientVolume.value,
},
extra_ingredient: undefined,

View File

@ -41,14 +41,14 @@
type="number"
/>
<q-input
v-model.number="newDrink.cost_price_package_netto"
v-model.number="newDrink.cost_per_package"
class="col-sm-4 col-xs-6 q-pa-sm"
filled
label="Preis Netto/Gebinde"
type="number"
/>
<q-input
v-model="cost_price_pro_volume"
v-model.number="cost_per_volume"
class="col-sm-4 col-xs-6 q-pa-sm"
filled
label="Preis mit 19%/Liter"
@ -78,8 +78,8 @@ export default defineComponent({
package_size: undefined,
name: '',
volume: undefined,
cost_price_pro_volume: undefined,
cost_price_package_netto: undefined,
cost_per_volume: undefined,
cost_per_package: undefined,
tags: [],
type: undefined,
volumes: [],
@ -88,24 +88,24 @@ export default defineComponent({
const calc_price_pro_volume = computed(
() =>
!!newDrink.value.cost_price_package_netto &&
!!newDrink.value.cost_per_package &&
!!newDrink.value.volume &&
!!newDrink.value.package_size
);
const cost_price_pro_volume = computed({
const cost_per_volume = computed({
get: () => {
if (calc_price_pro_volume.value) {
const retVal =
((newDrink.value.cost_price_package_netto || 0) /
((newDrink.value.cost_per_package || 0) /
((newDrink.value.volume || 0) * (newDrink.value.package_size || 0))) *
1.19;
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
newDrink.value.cost_price_pro_volume = Math.round(retVal * 1000) / 1000;
newDrink.value.cost_per_volume = Math.round(retVal * 1000) / 1000;
}
return newDrink.value.cost_price_pro_volume;
return newDrink.value.cost_per_volume;
},
set: (val) => {
newDrink.value.cost_price_pro_volume = val;
newDrink.value.cost_per_volume = val;
},
});
@ -124,7 +124,7 @@ export default defineComponent({
drinkTypes: computed(() => store.drinkTypes),
newDrink,
calc_price_pro_volume,
cost_price_pro_volume,
cost_per_volume,
addDrink,
cancelAddDrink,
notEmpty,

View File

@ -45,7 +45,7 @@ export default defineComponent({
volume.value.ingredients.forEach((ingredient) => {
if (ingredient.drink_ingredient) {
const _drink = store.drinks.find(
(a) => a.id === ingredient.drink_ingredient?.drink_ingredient_id
(a) => a.id === ingredient.drink_ingredient?.ingredient_id
);
retVal +=
ingredient.drink_ingredient.volume *

View File

@ -0,0 +1,100 @@
<template>
<q-page padding>
<q-card>
<q-table title="Getränke" :columns="columns_drinks" :rows="drinks" row-key="name">
<template #body-cell-volumes="props">
<q-td :props="props">
<q-table
:columns="columns_volumes"
:rows="props.row.volumes"
hide-header
:hide-bottom="props.row.volumes.length < 5"
flat
>
<template #body-cell-prices="props_volumes">
<q-td :props="props_volumes">
<q-table
:columns="columns_prices"
:rows="props_volumes.row.prices"
hide-header
:hide-bottom="props_volumes.row.prices.length < 5"
flat
>
<template #body-cell-public="props_prices">
<q-td :props="props_prices">
<q-toggle v-model="props_prices.row.public" disable />
</q-td>
</template>
</q-table>
</q-td>
</template>
</q-table>
</q-td>
</template>
</q-table>
</q-card>
</q-page>
</template>
<script lang="ts">
import { defineComponent, onBeforeMount, computed } from 'vue';
import { usePricelistStore } from '../store';
export default defineComponent({
name: 'Pricelist',
setup() {
const store = usePricelistStore();
onBeforeMount(() => {
void store.getDrinks();
});
const drinks = computed(() => store.drinks);
const columns_drinks = [
{
name: 'name',
label: 'Getränk',
field: 'name',
align: 'center',
},
{
name: 'volumes',
label: 'Preise',
field: 'volumes',
align: 'center',
},
];
const columns_volumes = [
{
name: 'volume',
label: 'Inhalt',
field: 'volume',
format: (val: number) => `${val.toFixed(3)}L`,
align: 'left',
},
{
name: 'prices',
label: 'Preise',
field: 'prices',
},
];
const columns_prices = [
{
name: 'price',
label: 'Preis',
field: 'price',
format: (val: number) => `${val.toFixed(2)}`,
},
{
name: 'description',
label: 'Beschreibung',
field: 'description',
},
{
name: 'public',
label: 'Öffentlich',
field: 'public',
},
];
return { columns_drinks, columns_volumes, columns_prices, drinks };
},
});
</script>

View File

@ -1,15 +0,0 @@
<template>
<Pricelist />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Pricelist from '../components/Pricelist.vue';
export default defineComponent({
name: 'PricelistPage',
components: { Pricelist },
});
</script>
<style scoped></style>

View File

@ -19,7 +19,7 @@ export const innerRoutes: FG_Plugin.MenuRoute[] = [
route: {
path: 'pricelist',
name: 'drinks-pricelist',
component: () => import('../pages/PricelistP.vue'),
component: () => import('../pages/Pricelist.vue'),
},
},
{

View File

@ -53,8 +53,8 @@ class Drink {
package_size,
name,
volume,
cost_price_pro_volume,
cost_price_package_netto,
cost_per_volume,
cost_per_package,
tags,
type,
uuid,
@ -65,15 +65,13 @@ class Drink {
this.package_size = package_size;
this.name = name;
this.volume = volume;
this.cost_price_package_netto = cost_price_package_netto;
this._cost_price_pro_volume = cost_price_pro_volume;
this.cost_per_package = cost_per_package;
this.cost_per_volume = cost_per_volume;
this.cost_price_pro_volume = computed({
get: () => {
if (!!this.volume && !!this.package_size && !!this.cost_price_package_netto) {
if (!!this.volume && !!this.package_size && !!this.cost_per_package) {
const retVal =
((this.cost_price_package_netto || 0) /
((this.volume || 0) * (this.package_size || 0))) *
1.19;
((this.cost_per_package || 0) / ((this.volume || 0) * (this.package_size || 0))) * 1.19;
this._cost_price_pro_volume = Math.round(retVal * 1000) / 1000;
}
@ -289,7 +287,7 @@ export const usePricelistStore = defineStore({
volume.ingredients.forEach((ingredient) => {
if (ingredient.drink_ingredient) {
const _drink = usePricelistStore().drinks.find(
(a) => a.id === ingredient.drink_ingredient?.drink_ingredient_id
(a) => a.id === ingredient.drink_ingredient?.ingredient_id
);
retVal +=
ingredient.drink_ingredient.volume *

View File

@ -15,32 +15,30 @@
</q-card>
</q-dialog>
<q-page padding>
<q-card>
<q-card-section>
<q-table title="Veranstaltungstypen" :data="rows" row-key="jobid" :columns="columns">
<template #top-right>
<q-input v-model="newEventType" dense placeholder="Neuer Typ" />
<q-card>
<q-card-section>
<q-table title="Veranstaltungstypen" :rows="rows" row-key="jobid" :columns="columns">
<template #top-right>
<q-input v-model="newEventType" dense placeholder="Neuer Typ" />
<div></div>
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addType" />
</template>
<template #body-cell-actions="props">
<!-- <q-btn :label="item"> -->
<!-- {{ item.row.name }} -->
<q-td :props="props" align="right" :auto-width="true">
<q-btn
round
icon="mdi-pencil"
@click="editType({ id: props.row.id, name: props.row.name })"
/>
<q-btn round icon="mdi-delete" @click="deleteType(props.row.id)" />
</q-td>
</template>
</q-table>
</q-card-section>
</q-card>
</q-page>
<div></div>
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addType" />
</template>
<template #body-cell-actions="props">
<!-- <q-btn :label="item"> -->
<!-- {{ item.row.name }} -->
<q-td :props="props" align="right" :auto-width="true">
<q-btn
round
icon="mdi-pencil"
@click="editType({ id: props.row.id, name: props.row.name })"
/>
<q-btn round icon="mdi-delete" @click="deleteType(props.row.id)" />
</q-td>
</template>
</q-table>
</q-card-section>
</q-card>
</div>
</template>
@ -59,7 +57,7 @@ export default defineComponent({
const actualEvent = ref(emptyEvent);
const newEventName = ref('');
onBeforeMount(() => store.getEventTypes());
onBeforeMount(async () => await store.getEventTypes());
const rows = computed(() => store.eventTypes);

View File

@ -15,32 +15,30 @@
</q-card>
</q-dialog>
<q-page padding>
<q-card>
<q-card-section>
<q-table title="Diensttypen" :data="rows" row-key="jobid" :columns="columns">
<template #top-right>
<q-input v-model="newJob" dense placeholder="Neuer Typ" />
<q-card>
<q-card-section>
<q-table title="Diensttypen" :rows="rows" row-key="jobid" :columns="columns">
<template #top-right>
<q-input v-model="newJob" dense placeholder="Neuer Typ" />
<div></div>
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addType" />
</template>
<template #body-cell-actions="props">
<!-- <q-btn :label="item"> -->
<!-- {{ item.row.name }} -->
<q-td :props="props" align="right" :auto-width="true">
<q-btn
round
icon="mdi-pencil"
@click="editType({ id: props.row.id, name: props.row.name })"
/>
<q-btn round icon="mdi-delete" @click="deleteType(props.row.id)" />
</q-td>
</template>
</q-table>
</q-card-section>
</q-card>
</q-page>
<div></div>
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addType" />
</template>
<template #body-cell-actions="props">
<!-- <q-btn :label="item"> -->
<!-- {{ item.row.name }} -->
<q-td :props="props" align="right" :auto-width="true">
<q-btn
round
icon="mdi-pencil"
@click="editType({ id: props.row.id, name: props.row.name })"
/>
<q-btn round icon="mdi-delete" @click="deleteType(props.row.id)" />
</q-td>
</template>
</q-table>
</q-card-section>
</q-card>
</div>
</template>

View File

@ -84,6 +84,7 @@ export default defineComponent({
async function enrollForJob() {
const newService: FG.Service = {
userid: mainStore.currentUser.userid,
is_backup: false,
value: 1,
};
try {
@ -104,6 +105,7 @@ export default defineComponent({
async function signOutFromJob() {
const newService: FG.Service = {
userid: mainStore.currentUser.userid,
is_backup: false,
value: -1,
};
try {

View File

@ -1,16 +1,16 @@
export const PERMISSIONS = {
// Can create events
CREATE: 'schedule_create',
CREATE: 'events_create',
// Can edit events
EDIT: 'schedule_edit',
EDIT: 'events_edit',
// Can delete events
DELETE: 'schedule_delete',
DELETE: 'events_delete',
// Can create and edit EventTypes
EVENT_TYPE: 'schedule_event_type',
EVENT_TYPE: 'events_event_type',
// Can create and edit JobTypes
JOB_TYPE: 'schedule_job_type',
JOB_TYPE: 'events_job_type',
// Can self assign to jobs
ASSIGN: 'schedule_assign',
ASSIGN: 'events_assign',
// Can assign other users to jobs
ASSIGN_OTHER: 'schedule_assign_other',
ASSIGN_OTHER: 'events_assign_other',
};

View File

@ -6,7 +6,7 @@ const plugin: FG_Plugin.Plugin = {
name: 'User',
innerRoutes: routes,
requiredModules: [],
requiredBackendModules: ['auth'],
requiredBackendModules: ['auth', 'users', 'roles'],
version: '0.0.1',
widgets: [
{

View File

@ -41,6 +41,7 @@ export const useMainStore = defineStore({
state: () => ({
session: loadCurrentSession(),
user: loadUser(),
notifications: [] as Array<FG.Notification>,
}),
getters: {
@ -123,5 +124,33 @@ export const useMainStore = defineStore({
response && 'status' in response ? (<AxiosResponse>response).status : false
);
},
async loadNotifications() {
const params =
this.notifications.length > 0
? { from: this.notifications[this.notifications.length - 1].time }
: {};
const { data } = await api.get<FG.Notification[]>('/notifications', { params: params });
data.forEach((n) => {
n.time = new Date(n.time);
if (window.Notification.permission === 'granted')
new window.Notification(n.text, {
timestamp: n.time.getTime(),
});
});
this.notifications.push(...data);
},
async removeNotification(id: number) {
const idx = this.notifications.findIndex((n) => n.id === id);
if (idx >= 0)
try {
this.notifications.splice(idx, 1);
await api.delete(`/notifications/${id}`);
} catch (error) {
if (this.notifications.length > idx)
this.notifications.splice(idx, this.notifications.length - idx - 1);
}
},
},
});

View File

@ -1027,10 +1027,10 @@
resolved "https://registry.yarnpkg.com/@positron/stack-trace/-/stack-trace-1.0.0.tgz#14fcc712a530038ef9be1ce6952315a839f466a8"
integrity sha1-FPzHEqUwA475vhzmlSMVqDn0Zqg=
"@quasar/app@^3.0.0-beta.9":
version "3.0.0-beta.9"
resolved "https://registry.yarnpkg.com/@quasar/app/-/app-3.0.0-beta.9.tgz#8d5fb2056aaf5a03919b63c9c655933281e8beed"
integrity sha512-Wt12LLWTyp1GMw17xVVScvjom9EILIlnuV4xrgZ7WTfwwZ18jcqtf3pTs2NMeOgIwohlP2qLsI5JQW9wLylQzw==
"@quasar/app@^3.0.0-beta.10":
version "3.0.0-beta.10"
resolved "https://registry.yarnpkg.com/@quasar/app/-/app-3.0.0-beta.10.tgz#f4401fa64f9f94b7e643560fb8968f3f7250578d"
integrity sha512-KC5dmW7hOJ0x634vgyb98cjjia2Mj0BySgq1JghMGiCqq3noF6E9DS9UoF3ru9HUVRUtxfLe73Su8V0s1UoQZg==
dependencies:
"@quasar/babel-preset-app" "2.0.1"
"@quasar/fastclick" "1.1.4"
@ -1041,7 +1041,7 @@
"@types/terser-webpack-plugin" "3.0.0"
"@types/webpack" "4.41.26"
"@types/webpack-bundle-analyzer" "3.9.1"
"@types/webpack-dev-server" "3.11.1"
"@types/webpack-dev-server" "3.11.2"
"@vue/compiler-sfc" "3.0.6"
"@vue/server-renderer" "3.0.6"
archiver "5.2.0"
@ -1135,10 +1135,10 @@
core-js "^3.6.5"
core-js-compat "^3.6.5"
"@quasar/extras@^1.9.19":
version "1.9.19"
resolved "https://registry.yarnpkg.com/@quasar/extras/-/extras-1.9.19.tgz#8e511117ccd8ec5bbed7038b9dad1749052376b8"
integrity sha512-A1IO0dzfUtRkyKq3QC7ZQNvhLeJey2ET8MvRX7oV0Qe+g30jy/4pr1ZhO7GylkDAoLT3C9eY8t2/5Anrl0AHdA==
"@quasar/extras@^1.10.0":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@quasar/extras/-/extras-1.10.0.tgz#1cf13d299e80e1396b2f982e1663b89dd54f3e8e"
integrity sha512-H71Y/6pxunwiEN+oo9OBGM96ncM2QreVdnb2t2iStVHduju3nnypw9euBCshhYxKE/ORHZoOBRDoiddUOyaUdA==
"@quasar/fastclick@1.1.4":
version "1.1.4"
@ -1148,7 +1148,7 @@
"@quasar/quasar-app-extension-qcalendar@file:deps/quasar-ui-qcalendar/app-extension":
version "4.0.0-alpha.1"
dependencies:
"@quasar/quasar-ui-qcalendar" "link:../../../../../.cache/yarn/v6/npm-@quasar-quasar-app-extension-qcalendar-4.0.0-alpha.1-0eac22e6-3d93-4296-9ecf-77ea02e6ad1a-1616339967660/node_modules/@quasar/ui"
"@quasar/quasar-ui-qcalendar" "link:../../../../../.cache/yarn/v6/npm-@quasar-quasar-app-extension-qcalendar-4.0.0-alpha.1-3c86cc72-2d95-4dfe-9e1e-2f553d66f91e-1616893646708/node_modules/@quasar/ui"
"@quasar/quasar-ui-qcalendar@link:deps/quasar-ui-qcalendar/ui":
version "0.0.0"
@ -1266,13 +1266,6 @@
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50"
integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==
"@types/http-proxy-middleware@*":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-1.0.0.tgz#4370a52766782e9c4f0be2ef79c3dd47aef5f428"
integrity sha512-/s8lFX6rT43hSPqjjD8KNuu0SkPKY7uIdR6u9DCxVqCRhAvfKxGbVOixJsAT2mdpSnCyrGFAGoB39KFh6tmRxw==
dependencies:
http-proxy-middleware "*"
"@types/http-proxy@^1.17.4":
version "1.17.5"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.5.tgz#c203c5e6e9dc6820d27a40eb1e511c70a220423d"
@ -1365,16 +1358,16 @@
dependencies:
"@types/webpack" "*"
"@types/webpack-dev-server@3.11.1":
version "3.11.1"
resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#f8f4dac1da226d530bd15a1d5dc34b23ba766ccb"
integrity sha512-rIb+LtUkKnh7+oIJm3WiMJONd71Q0lZuqGLcSqhZ5qjN9gV/CNmZe7Bai+brnBPZ/KVYOsr+4bFLiNZwjBicLw==
"@types/webpack-dev-server@3.11.2":
version "3.11.2"
resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#73915a7d9e0a9b5e010a2388a46f68ab3f770ef8"
integrity sha512-13w1VhaghN+G1rYjkBPgN/GFRoHd9uI2fwK9cSKvLutdmZ22L9iicFEvt69by40DP2I6uNcClaGTyPY6nYhIgQ==
dependencies:
"@types/connect-history-api-fallback" "*"
"@types/express" "*"
"@types/http-proxy-middleware" "*"
"@types/serve-static" "*"
"@types/webpack" "*"
http-proxy-middleware "^1.0.0"
"@types/webpack-env@^1.16.0":
version "1.16.0"
@ -5235,17 +5228,6 @@ http-proxy-agent@^4.0.1:
agent-base "6"
debug "4"
http-proxy-middleware@*:
version "1.0.6"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz#0618557722f450375d3796d701a8ac5407b3b94e"
integrity sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==
dependencies:
"@types/http-proxy" "^1.17.4"
http-proxy "^1.18.1"
is-glob "^4.0.1"
lodash "^4.17.20"
micromatch "^4.0.2"
http-proxy-middleware@0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
@ -5256,6 +5238,17 @@ http-proxy-middleware@0.19.1:
lodash "^4.17.11"
micromatch "^3.1.10"
http-proxy-middleware@^1.0.0:
version "1.0.6"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz#0618557722f450375d3796d701a8ac5407b3b94e"
integrity sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==
dependencies:
"@types/http-proxy" "^1.17.4"
http-proxy "^1.18.1"
is-glob "^4.0.1"
lodash "^4.17.20"
micromatch "^4.0.2"
http-proxy@^1.17.0, http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
@ -8236,10 +8229,10 @@ qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
quasar@^2.0.0-beta.9:
version "2.0.0-beta.9"
resolved "https://registry.yarnpkg.com/quasar/-/quasar-2.0.0-beta.9.tgz#0247a3512f3bdffd29f8f2a3f33fc91e62a91697"
integrity sha512-xqYKBQMF5ntM9RUr/eHFsSM6onXTzpwTcoBnM0YL6/QknBlSBHXltjG7pJmKMSm62ZRq1YeOdLsC9nchHgSrCQ==
quasar@^2.0.0-beta.11:
version "2.0.0-beta.11"
resolved "https://registry.yarnpkg.com/quasar/-/quasar-2.0.0-beta.11.tgz#78f21abe94caa78fe17ad17ce945d09dfda9e5d2"
integrity sha512-YG+iVkd1LNbo0MFSrPl1npEW02FfVeD4+/98nYPz3pfZEdOy1kiOF7N9Ij7RDC8x0/+9Ans9mgBvs0xjg9YxyA==
query-string@^4.1.0:
version "4.3.4"