script[setup]: file components (#18455)

This commit is contained in:
Rijk van Zanten
2023-05-03 12:22:26 -04:00
committed by GitHub
parent b57b13f118
commit cae0534766
3 changed files with 150 additions and 192 deletions

View File

@@ -23,9 +23,9 @@
</v-dialog>
</template>
<script lang="ts">
<script lang="ts" setup>
import api from '@/api';
import { computed, defineComponent, ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import FilePreview from '@/views/private/components/file-preview.vue';
import { nanoid } from 'nanoid';
@@ -40,73 +40,64 @@ type File = {
title: string;
};
export default defineComponent({
components: { FilePreview },
props: {
id: {
type: String,
required: true,
},
modelValue: {
type: Boolean,
default: undefined,
},
const props = defineProps<{
id: string;
modelValue?: boolean;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void;
}>();
const localActive = ref(false);
const internalActive = computed({
get() {
return props.modelValue === undefined ? localActive.value : props.modelValue;
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const localActive = ref(false);
const internalActive = computed({
get() {
return props.modelValue === undefined ? localActive.value : props.modelValue;
},
set(newActive: boolean) {
localActive.value = newActive;
emit('update:modelValue', newActive);
},
});
const loading = ref(false);
const file = ref<File | null>(null);
const cacheBuster = ref(nanoid());
const fileSrc = computed(() => {
return getRootPath() + `assets/${props.id}?cache-buster=${cacheBuster.value}`;
});
watch(
[() => props.id, internalActive],
([newID, newActive]) => {
if (newActive && newID) {
fetchFile();
}
},
{ immediate: true }
);
return { internalActive, cacheBuster, loading, file, fileSrc };
async function fetchFile() {
cacheBuster.value = nanoid();
loading.value = true;
try {
const response = await api.get(`/files/${props.id}`, {
params: {
fields: ['type', 'width', 'height', 'title'],
},
});
file.value = response.data.data;
} catch (err: any) {
unexpectedError(err);
} finally {
loading.value = false;
}
}
set(newActive: boolean) {
localActive.value = newActive;
emit('update:modelValue', newActive);
},
});
const loading = ref(false);
const file = ref<File | null>(null);
const cacheBuster = ref(nanoid());
const fileSrc = computed(() => {
return getRootPath() + `assets/${props.id}?cache-buster=${cacheBuster.value}`;
});
watch(
[() => props.id, internalActive],
([newID, newActive]) => {
if (newActive && newID) {
fetchFile();
}
},
{ immediate: true }
);
async function fetchFile() {
cacheBuster.value = nanoid();
loading.value = true;
try {
const response = await api.get(`/files/${props.id}`, {
params: {
fields: ['type', 'width', 'height', 'title'],
},
});
file.value = response.data.data;
} catch (err: any) {
unexpectedError(err);
} finally {
loading.value = false;
}
}
</script>
<style lang="scss" scoped>

View File

@@ -5,7 +5,7 @@
clickable
:active="currentFolder === folder.id"
:disabled="disabled"
@click="clickHandler(folder.id)"
@click="clickHandler?.(folder.id)"
>
<v-list-item-icon><v-icon :name="currentFolder === folder.id ? 'folder_open' : 'folder'" /></v-list-item-icon>
<v-list-item-content>{{ folder.name }}</v-list-item-content>
@@ -15,7 +15,7 @@
clickable
:active="currentFolder === folder.id"
:disabled="disabled"
@click="clickHandler(folder.id)"
@click="clickHandler?.(folder.id)"
>
<template #activator>
<v-list-item-icon>
@@ -29,45 +29,25 @@
:folder="childFolder"
:current-folder="currentFolder"
:click-handler="clickHandler"
:disabled="disabledFolders.includes(childFolder.id)"
:disabled="disabledFolders?.includes(childFolder.id)"
:disabled-folders="disabledFolders"
/>
</v-list-group>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
<script lang="ts" setup>
type Folder = {
id: string;
name: string;
children: Folder[];
};
export default defineComponent({
name: 'FolderPickerListItem',
props: {
folder: {
type: Object as PropType<Folder>,
required: true,
},
currentFolder: {
type: String,
default: null,
},
clickHandler: {
type: Function,
default: () => undefined,
},
disabled: {
type: Boolean,
default: false,
},
disabledFolders: {
type: Array as PropType<string[]>,
default: () => [],
},
},
});
defineProps<{
folder: Folder;
currentFolder: string | null;
clickHandler?: (folderId: string) => void;
disabled?: boolean;
disabledFolders?: string[];
}>();
</script>

View File

@@ -24,7 +24,7 @@
:folder="folder"
:current-folder="modelValue"
:click-handler="(id) => $emit('update:modelValue', id)"
:disabled="disabledFolders.includes(folder.id)"
:disabled="disabledFolders?.includes(folder.id)"
:disabled-folders="disabledFolders"
/>
</v-list-group>
@@ -33,9 +33,9 @@
</div>
</template>
<script lang="ts">
<script lang="ts" setup>
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, PropType } from 'vue';
import { computed, ref } from 'vue';
import api from '@/api';
import FolderPickerListItem from './folder-picker-list-item.vue';
import { unexpectedError } from '@/utils/unexpected-error';
@@ -52,104 +52,91 @@ type Folder = {
children: Folder[];
};
export default defineComponent({
components: { FolderPickerListItem },
props: {
disabledFolders: {
type: Array as PropType<string[]>,
default: () => [],
},
modelValue: {
type: String,
default: null,
},
},
emits: ['update:modelValue'],
setup(props) {
const { t } = useI18n();
const props = defineProps<{
disabledFolders?: string[];
modelValue: string | null;
}>();
const loading = ref(false);
const folders = ref<FolderRaw[]>([]);
defineEmits<{
(e: 'update:modelValue', value: string | null): void;
}>();
const tree = computed<Folder[]>(() => {
return folders.value
.filter((folder) => folder.parent === null)
.map((folder) => {
return {
...folder,
children: getChildFolders(folder),
};
});
const { t } = useI18n();
function getChildFolders(folder: FolderRaw): Folder[] {
return folders.value
.filter((childFolder) => {
return childFolder.parent === folder.id;
})
.map((childFolder) => {
return {
...childFolder,
children: getChildFolders(childFolder),
};
});
}
const loading = ref(false);
const folders = ref<FolderRaw[]>([]);
const tree = computed<Folder[]>(() => {
return folders.value
.filter((folder) => folder.parent === null)
.map((folder) => {
return {
...folder,
children: getChildFolders(folder),
};
});
const shouldBeOpen: string[] = [];
const folder = folders.value.find((folder) => folder.id === props.modelValue);
if (folder && folder.parent) parseFolder(folder.parent);
const startOpenFolders = ['root'];
for (const folderID of shouldBeOpen) {
if (startOpenFolders.includes(folderID) === false) {
startOpenFolders.push(folderID);
}
}
const selectedFolder = computed(() => {
return folders.value.find((folder) => folder.id === props.modelValue) || {};
});
const openFolders = ref(startOpenFolders);
fetchFolders();
return { t, loading, folders, tree, selectedFolder, openFolders };
async function fetchFolders() {
if (folders.value.length > 0) return;
loading.value = true;
try {
const response = await api.get(`/folders`, {
params: {
limit: -1,
sort: 'name',
},
});
folders.value = response.data.data;
} catch (err: any) {
unexpectedError(err);
} finally {
loading.value = false;
}
}
function parseFolder(id: string) {
if (!folders.value) return;
shouldBeOpen.push(id);
const folder = folders.value.find((folder) => folder.id === id);
if (folder && folder.parent) {
parseFolder(folder.parent);
}
}
},
function getChildFolders(folder: FolderRaw): Folder[] {
return folders.value
.filter((childFolder) => {
return childFolder.parent === folder.id;
})
.map((childFolder) => {
return {
...childFolder,
children: getChildFolders(childFolder),
};
});
}
});
const shouldBeOpen: string[] = [];
const selectedFolder = folders.value.find((folder) => folder.id === props.modelValue);
if (selectedFolder && selectedFolder.parent) parseFolder(selectedFolder.parent);
const startOpenFolders = ['root'];
for (const folderID of shouldBeOpen) {
if (startOpenFolders.includes(folderID) === false) {
startOpenFolders.push(folderID);
}
}
const openFolders = ref(startOpenFolders);
fetchFolders();
async function fetchFolders() {
if (folders.value.length > 0) return;
loading.value = true;
try {
const response = await api.get(`/folders`, {
params: {
limit: -1,
sort: 'name',
},
});
folders.value = response.data.data;
} catch (err: any) {
unexpectedError(err);
} finally {
loading.value = false;
}
}
function parseFolder(id: string) {
if (!folders.value) return;
shouldBeOpen.push(id);
const folder = folders.value.find((folder) => folder.id === id);
if (folder && folder.parent) {
parseFolder(folder.parent);
}
}
</script>
<style lang="scss" scoped>