mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-02 20:15:24 +02:00
refactor(frontend): 🚧 Add group/user CRUD support for admins
This commit is contained in:
parent
917177da5b
commit
695d7e96ae
46 changed files with 2015 additions and 102 deletions
|
@ -18,6 +18,7 @@
|
|||
:label="inputField.label"
|
||||
:name="inputField.varName"
|
||||
:hint="inputField.hint || ''"
|
||||
:disabled="updateMode && inputField.fixed"
|
||||
@change="emitBlur"
|
||||
/>
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<v-card flat class="pb-2">
|
||||
<h2>{{ title }}</h2>
|
||||
<h2 class="headline">{{ title }}</h2>
|
||||
<BaseDivider width="200px" color="primary" class="my-2" thickness="1px" />
|
||||
<p class="pb-0 mb-0">
|
||||
<slot />
|
||||
</p>
|
||||
|
@ -12,8 +13,8 @@ export default {
|
|||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: "Place Holder"
|
||||
}
|
||||
}
|
||||
}
|
||||
default: "Place Holder",
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
64
frontend/components/global/BaseColorPicker.vue
Normal file
64
frontend/components/global/BaseColorPicker.vue
Normal file
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="text-center">
|
||||
<h3>{{ buttonText }}</h3>
|
||||
</div>
|
||||
<v-text-field v-model="color" hide-details class="ma-0 pa-0" solo>
|
||||
<template #append>
|
||||
<v-menu v-model="menu" top nudge-bottom="105" nudge-left="16" :close-on-content-click="false">
|
||||
<template #activator="{ on }">
|
||||
<div :style="swatchStyle" swatches-max-height="300" v-on="on" />
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-text class="pa-0">
|
||||
<v-color-picker v-model="color" flat mode="hexa" show-swatches />
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
buttonText: String,
|
||||
value: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
swatches: false,
|
||||
color: this.value || "#1976D2",
|
||||
mask: "!#XXXXXXXX",
|
||||
menu: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
swatchStyle() {
|
||||
const { value, menu } = this;
|
||||
return {
|
||||
backgroundColor: value,
|
||||
cursor: "pointer",
|
||||
height: "30px",
|
||||
width: "30px",
|
||||
borderRadius: menu ? "50%" : "4px",
|
||||
transition: "border-radius 200ms ease-in-out",
|
||||
};
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
color() {
|
||||
this.updateColor();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateColor() {
|
||||
this.$emit("input", this.color);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -33,9 +33,12 @@
|
|||
|
||||
<BaseButton v-if="$listeners.delete" delete secondary @click="deleteEvent" />
|
||||
<BaseButton v-if="$listeners.confirm" :color="color" type="submit" @click="$emit('confirm')">
|
||||
<template #icon>
|
||||
{{ $globals.icons.check }}
|
||||
</template>
|
||||
{{ $t("general.confirm") }}
|
||||
</BaseButton>
|
||||
<BaseButton v-else-if="$listeners.submit" type="submit" @click="submitEvent">
|
||||
<BaseButton v-if="$listeners.submit" type="submit" @click="submitEvent">
|
||||
{{ submitText }}
|
||||
</BaseButton>
|
||||
</slot>
|
||||
|
@ -108,6 +111,7 @@ export default defineComponent({
|
|||
},
|
||||
dialog(val) {
|
||||
if (val) this.submitted = false;
|
||||
if (!val) this.$emit("close");
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -130,4 +134,9 @@ export default defineComponent({
|
|||
});
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style>
|
||||
.top-dialog {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-divider :width="width" class="mx-auto" :class="color" :style="`border-width: ${thickness} !important`" />
|
||||
<v-divider :width="width" :class="color" :style="`border-width: ${thickness} !important`" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -7,16 +7,16 @@ export default {
|
|||
props: {
|
||||
width: {
|
||||
type: String,
|
||||
default: "100px"
|
||||
default: "100px",
|
||||
},
|
||||
thickness: {
|
||||
type: String,
|
||||
default: "2px"
|
||||
default: "2px",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "accent"
|
||||
}
|
||||
}
|
||||
}
|
||||
default: "accent",
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
103
frontend/components/global/BaseStatCard.vue
Normal file
103
frontend/components/global/BaseStatCard.vue
Normal file
|
@ -0,0 +1,103 @@
|
|||
w<template>
|
||||
<v-card v-bind="$attrs" :class="classes" class="v-card--material pa-3">
|
||||
<div class="d-flex grow flex-wrap">
|
||||
<slot name="avatar">
|
||||
<v-sheet
|
||||
:color="color"
|
||||
:max-height="icon ? 90 : undefined"
|
||||
:width="icon ? 'auto' : '100%'"
|
||||
elevation="6"
|
||||
class="text-start v-card--material__heading mb-n6 mt-n10 pa-7"
|
||||
dark
|
||||
>
|
||||
<v-icon v-if="icon" size="40" v-text="icon" />
|
||||
<div v-if="text" class="headline font-weight-thin" v-text="text" />
|
||||
</v-sheet>
|
||||
</slot>
|
||||
|
||||
<div v-if="$slots['after-heading']" class="ml-auto">
|
||||
<slot name="after-heading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
|
||||
<template v-if="$slots.actions">
|
||||
<v-divider class="mt-2" />
|
||||
|
||||
<v-card-actions class="pb-0">
|
||||
<slot name="actions" />
|
||||
</v-card-actions>
|
||||
</template>
|
||||
|
||||
<template v-if="$slots.bottom">
|
||||
<v-divider v-if="!$slots.actions" class="mt-2" />
|
||||
|
||||
<div class="pb-0">
|
||||
<slot name="bottom" />
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MaterialCard",
|
||||
|
||||
props: {
|
||||
avatar: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "primary",
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
image: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
classes() {
|
||||
return {
|
||||
"v-card--material--has-heading": this.hasHeading,
|
||||
"mt-3": this.$vuetify.breakpoint.name === "xs" || this.$vuetify.breakpoint.name === "sm",
|
||||
};
|
||||
},
|
||||
hasHeading() {
|
||||
return false;
|
||||
},
|
||||
hasAltHeading() {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-card--material
|
||||
&__avatar
|
||||
position: relative
|
||||
top: -64px
|
||||
margin-bottom: -32px
|
||||
|
||||
&__heading
|
||||
position: relative
|
||||
top: -40px
|
||||
transition: .3s ease
|
||||
z-index: 1
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue