mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Add reusable image editor modal (#503)
* Install cropperjs * Add cropper js styles * Add editing image string * Track inner active state * Add temp edit button * Start on image editor modal * Add custom icons for image manipulation * Add image manipulation strings * Tweak cropper styles * Remove unused import * Save as blob * Expose getItem method for manual refreshes * Add cache-busting to file preview * Use new API post endpoint, emit refresh event on success * Add a cache buster to the image editor
This commit is contained in:
18
src/components/v-icon/custom-icons/flip_horizontal.vue
Normal file
18
src/components/v-icon/custom-icons/flip_horizontal.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template functional>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="2"
|
||||
>
|
||||
<path
|
||||
d="M 3 2 L 3 11 L 21 11 L 3 2 z M 5 5.2363281 L 12.527344 9 L 5 9 L 5 5.2363281 z M 3 13 L 3 22 L 21 13 L 3 13 z"
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {};
|
||||
</script>
|
||||
19
src/components/v-icon/custom-icons/flip_vertical.vue
Normal file
19
src/components/v-icon/custom-icons/flip_vertical.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template functional>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="2"
|
||||
>
|
||||
<path
|
||||
d="M3,2 L3,11 L21,11 L3,2 Z M5,5.2363281 L12.527344,9 L5,9 L5,5.2363281 Z M3,13 L3,22 L21,13 L3,13 Z"
|
||||
transform="translate(12.000000, 12.000000) rotate(-90.000000) translate(-12.000000, -12.000000) "
|
||||
></path>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {};
|
||||
</script>
|
||||
@@ -25,6 +25,8 @@ import CustomIconGrid6 from './custom-icons/grid_6.vue';
|
||||
import CustomIconSignalWifi1Bar from './custom-icons/signal_wifi_1_bar.vue';
|
||||
import CustomIconSignalWifi2Bar from './custom-icons/signal_wifi_2_bar.vue';
|
||||
import CustomIconSignalWifi3Bar from './custom-icons/signal_wifi_3_bar.vue';
|
||||
import CustomIconFlipHorizontal from './custom-icons/flip_horizontal.vue';
|
||||
import CustomIconFlipVertical from './custom-icons/flip_vertical.vue';
|
||||
|
||||
const customIcons: string[] = [
|
||||
'box',
|
||||
@@ -37,6 +39,8 @@ const customIcons: string[] = [
|
||||
'signal_wifi_1_bar',
|
||||
'signal_wifi_2_bar',
|
||||
'signal_wifi_3_bar',
|
||||
'flip_horizontal',
|
||||
'flip_vertical',
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
@@ -51,6 +55,8 @@ export default defineComponent({
|
||||
CustomIconSignalWifi1Bar,
|
||||
CustomIconSignalWifi2Bar,
|
||||
CustomIconSignalWifi3Bar,
|
||||
CustomIconFlipHorizontal,
|
||||
CustomIconFlipVertical,
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-dialog :active="active" @toggle="$emit('toggle', $event)" :persistent="persistent">
|
||||
<v-dialog v-model="_active" :persistent="persistent">
|
||||
<template #activator="{ on }">
|
||||
<slot name="activator" v-bind="{ on }" />
|
||||
</template>
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="spacer" />
|
||||
<v-icon name="" />
|
||||
</header>
|
||||
<div class="content">
|
||||
<div class="content" :class="{ 'no-padding': noPadding }">
|
||||
<v-overlay
|
||||
v-if="$slots.sidebar"
|
||||
absolute
|
||||
@@ -32,14 +32,14 @@
|
||||
</main>
|
||||
</div>
|
||||
<footer class="footer" v-if="$slots.footer || $scopedSlots.footer">
|
||||
<slot name="footer" v-bind="{ close: () => $emit('toggle', false) }" />
|
||||
<slot name="footer" v-bind="{ close: () => (_active = false) }" />
|
||||
</footer>
|
||||
</article>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from '@vue/composition-api';
|
||||
import { defineComponent, ref, computed } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
model: {
|
||||
@@ -57,17 +57,33 @@ export default defineComponent({
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: undefined,
|
||||
},
|
||||
persistent: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
noPadding: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
setup(props, { emit }) {
|
||||
const sidebarActive = ref(false);
|
||||
|
||||
return { sidebarActive };
|
||||
const localActive = ref(false);
|
||||
|
||||
const _active = computed({
|
||||
get() {
|
||||
return props.active === undefined ? localActive.value : props.active;
|
||||
},
|
||||
set(newActive: boolean) {
|
||||
localActive.value = newActive;
|
||||
emit('toggle', newActive);
|
||||
},
|
||||
});
|
||||
|
||||
return { sidebarActive, _active };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -165,6 +181,10 @@ export default defineComponent({
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-padding .main {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
|
||||
Reference in New Issue
Block a user