Skip to content

Commit

Permalink
#9 - Clean up & Get Items from Api
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianbinau committed Oct 5, 2023
1 parent a1c4a72 commit 9a45c03
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 42 deletions.
56 changes: 45 additions & 11 deletions src/components/files/FileBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import { computed, ref, type PropType } from 'vue';
import NoFiles from './NoFiles.vue';
import Folder from './Folder.vue';
import File from './File.vue';
import { FolderClass, FileClass, ItemClass } from '@lib/items';
import { FolderClass, FileClass, ItemClass, type FolderType } from '@lib/items';
import { api } from '@lib/helpers';
const props = defineProps({
modelValue: {
type: Object as PropType<FolderClass>,
type: Object as PropType<FolderType>,
required: false,
},
});
Expand All @@ -38,19 +39,52 @@ const items = ref<ItemClass[]>([]);
getItems();
function getItems() {
console.log(props.modelValue instanceof FolderClass);
if (props.modelValue instanceof FolderClass) {
//
}
fetch(
api(
`${
ItemClass.isItem(props.modelValue) && FolderClass.isFolder(props.modelValue)
? props.modelValue.id
: ''
}`,
),
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
},
)
.then(async (response) => {
if (!response.ok) {
if (response.status >= 400 && response.status < 500) {
throw new Error((await response.json()).error);
}
for (let i = 0; i < 29; i++) {
const item =
Math.random() > 0.5 ? FolderClass.create('jkghk', null) : FileClass.create('grffrw', null);
items.value.push(item);
}
throw new Error(await response.text());
}
const rawItems = await response.json();
for (let rawItem of rawItems) {
if (!ItemClass.isItem(rawItem)) continue;
let item = ItemClass.getItemFromObject(rawItem);
if (item === null) continue;
items.value.push(item);
}
return items.value;
})
.catch((error) => {
console.error('Error:', error);
});
}
function updateItem(item: ItemClass) {
// Todo, Should find the item in the array and update it
console.log(item);
}
Expand Down
29 changes: 8 additions & 21 deletions src/components/files/Folder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
<template v-slot:content>
<a :href="url(`u/folder/${modelValue.id}`)">
<button
v-on:click.ctrl.prevent="
console.log('ctrl');
editingName = !editingName;
"
type="button"
:contenteditable="editingName ? 'true' : 'false'"
:class="classes"
class="h-[40px] rounded-lg bg-gradient-to-br px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800"
>
Expand All @@ -20,39 +15,33 @@
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Dashboard</a
>
</li>
<li>
<a
href="#"
:href="url(`u/folder/${modelValue.id}`)"
target="_blank"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Settings</a
>Open in new tab</a
>
</li>
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Earnings</a
>Change Name</a
>
</li>
</ul>
<div class="py-2">
<a
href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-600 dark:hover:text-white"
>Separated link</a
class="block px-4 py-2 text-sm text-red-500 hover:bg-gray-100 dark:text-red-500 dark:hover:bg-gray-600"
>Delete</a
>
</div>
</template>
</ContextMenu>
</template>

<script setup lang="ts">
import { ref, type PropType, computed } from 'vue';
import { type PropType, computed } from 'vue';
import { FolderClass } from '@lib/items';
import { url } from '@lib/helpers';
import ContextMenu from './ContextMenu.vue';
Expand All @@ -65,9 +54,7 @@ const props = defineProps({
});
defineEmits(['update:modelValue']);
const editingName = ref(false);
const classes = computed(() => {
return props.modelValue.colorClass + (editingName.value ? '' : '');
return props.modelValue.colorClass;
});
</script>
111 changes: 103 additions & 8 deletions src/lib/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export abstract class ItemClass {
private _mimeType: string;
private _ownerId: number;
private _parentId: number | null;
private _createdAt: Date | undefined;
private _updatedAt: Date | undefined;
private _createdAt: Date;
private _updatedAt: Date;
private _deletedAt: Date | null;

protected constructor(ItemObject: ItemType) {
Expand All @@ -17,9 +17,17 @@ export abstract class ItemClass {
this._mimeType = ItemObject.mimeType;
this._ownerId = ItemObject.ownerId;
this._parentId = ItemObject.parentId;
this._createdAt = ItemObject.createdAt || undefined;
this._updatedAt = ItemObject.updatedAt || undefined;
this._deletedAt = ItemObject.deletedAt || null;

const createdAt = ItemClass.convertDate(ItemObject.createdAt);
const updatedAt = ItemClass.convertDate(ItemObject.updatedAt);
const deletedAt = ItemClass.convertDate(ItemObject.deletedAt);

if (createdAt === null) throw new Error('Invalid createdAt');
if (updatedAt === null) throw new Error('Invalid updatedAt');

this._createdAt = createdAt;
this._updatedAt = updatedAt;
this._deletedAt = deletedAt;
}

get id() {
Expand Down Expand Up @@ -53,6 +61,76 @@ export abstract class ItemClass {
get deletedAt() {
return this._deletedAt;
}

static getItemFromObject(object: ItemType) {
if (FolderClass.isFolder(object)) return new FolderClass(object);
if (FileClass.isFile(object)) return new FileClass(object);

console.error('ItemClass.getItemFromObject: Invalid object');
return null;
}

static isItem(object: any): object is ItemType {
// Id
if (!('id' in object && typeof object.id === 'number')) return false;

// Name
if (!('name' in object && typeof object.name === 'string')) return false;

// MimeType
if (!('mimeType' in object && typeof object.mimeType === 'string')) return false;

// OwnerId
if (!('ownerId' in object && typeof object.ownerId === 'number')) return false;

// ParentId
if (
!(('parentId' in object && typeof object.parentId === 'number') || object.parentId === null)
)
return false;

// CreatedAt
if (
!(
'createdAt' in object &&
(object.createdAt === undefined ||
object.createdAt instanceof Date ||
typeof object.createdAt === 'string')
)
)
return false;

// UpdatedAt
if (
!(
'updatedAt' in object &&
(object.updatedAt === undefined ||
object.updatedAt instanceof Date ||
typeof object.updatedAt === 'string')
)
)
return false;

// DeletedAt
if (
!(
'deletedAt' in object &&
(object.deletedAt === undefined ||
object.deletedAt === null ||
object.deletedAt instanceof Date ||
typeof object.deletedAt === 'string')
)
)
return false;

return true;
}

private static convertDate(date: Date | string | undefined | null) {
if (typeof date === 'string') return new Date(date);
if (date instanceof Date) return date;
return null;
}
}

export type ItemType = {
Expand All @@ -61,9 +139,9 @@ export type ItemType = {
mimeType: string;
ownerId: number;
parentId: number | null;
createdAt?: Date;
updatedAt?: Date;
deletedAt?: Date | null;
createdAt?: Date | string;
updatedAt?: Date | string;
deletedAt?: Date | string | null;
};

/**
Expand Down Expand Up @@ -108,6 +186,16 @@ export class FolderClass extends ItemClass {
Math.floor(Math.random() * Object.keys(FolderColors).length)
] as FolderColor;
}

static isFolder(object: ItemType): object is FolderType {
// Color
if (!('color' in object && typeof object.color === 'string')) return false;

// MimeType
if (object.mimeType !== 'application/vnd.cloudstore.folder') return false;

return true;
}
}

export type FolderType = {
Expand Down Expand Up @@ -168,6 +256,13 @@ export class FileClass extends ItemClass {
get blobUrl() {
return this._blobUrl;
}

static isFile(object: ItemType): object is FileType {
// BlobUrl
if (!('blobUrl' in object && typeof object.blobUrl === 'string')) return false;

return true;
}
}

export type FileType = {
Expand Down
9 changes: 7 additions & 2 deletions src/pages/u/folder/[id].astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import LayoutSidebar from '@layouts/LayoutSidebar.astro';
import FileBrowser from '@components/files/FileBrowser.vue';
// @ts-ignore https://github.com/withastro/language-tools/issues/476
import { api, url } from '@lib/helpers';
import { FolderClass } from '@lib/items';
import { ItemClass, FolderClass } from '@lib/items';
const { id } = Astro.params;
Expand All @@ -23,8 +23,13 @@ if (!folderResponse || folderResponse?.statusCode <= 400) {
return Astro.redirect(url('404'));
}
// If the folder isn't a valid folder, redirect
if (!(ItemClass.isItem(folderResponse) && FolderClass.isFolder(folderResponse))) {
return Astro.redirect(url('404'));
}
// Otherwise, create a new folder instance
const folder = new FolderClass(folderResponse.data);
const folder = folderResponse;
// We can safely cast this as we know that middleware would have already checked for a valid user
const user = Astro.locals.user as User;
Expand Down

0 comments on commit 9a45c03

Please sign in to comment.