Skip to content

Commit 2e22ebc

Browse files
committed
feat(app): implement initial workspace flow
1 parent c7d3e46 commit 2e22ebc

23 files changed

+499
-1493
lines changed

package-lock.json

Lines changed: 14 additions & 1466 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/app/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<link rel="icon" href="/favicon.ico">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<title>Index-san</title>
8+
<link rel="preconnect" href="https://fonts.googleapis.com">
9+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10+
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
811
</head>
912
<body>
1013
<div id="app"></div>

packages/app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"chart.js": "^4.3.0",
2727
"chartjs-plugin-annotation": "^3.0.1",
2828
"highlight.js": "^11.8.0",
29+
"idb-keyval": "^6.2.1",
2930
"lodash": "^4.17.21",
3031
"markdown-it": "^13.0.1",
3132
"mime": "^3.0.0",
@@ -41,6 +42,7 @@
4142
"devDependencies": {
4243
"@types/lodash": "^4.14.195",
4344
"@types/mime": "^3.0.1",
45+
"@types/wicg-file-system-access": "^2023.10.4",
4446
"@vitejs/plugin-vue": "^4.2.3",
4547
"@vitest/coverage-c8": "^0.31.1",
4648
"@vue-macros/define-prop": "^0.1.7",

packages/app/src/App.vue

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,34 @@
11
<script setup lang="ts">
22
// import NNotify from '@modules/notify/components/NNotify.vue'
33
// import DDialog from '@modules/dialog/components/DDialog.vue'
4+
import { useRoute } from 'vue-router';
5+
import LayoutDefault from './layouts/LayoutDefault.vue'
6+
import LayoutEmpty from './layouts/LayoutEmpty.vue'
7+
8+
const route = useRoute()
9+
10+
const options: any = {
11+
default: LayoutDefault,
12+
empty: LayoutEmpty,
13+
}
14+
15+
function findLayout(key: string){
16+
const option = options[key as keyof typeof options]
17+
18+
if (!option) {
19+
return options.default
20+
}
21+
22+
return option
23+
24+
}
25+
426
527
</script>
628
<template>
729
<is-app>
8-
<router-view />
9-
</is-app>
30+
<component :is="findLayout($route.meta.layout as string)">
31+
<router-view />
32+
</component>
33+
</is-app>
1034
</template>

packages/app/src/components/IsApp.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ const theme = useTheme()
44
</script>
55
<template>
66
<div :class="[theme.dark ? 'dark' : '']">
7-
<div class="dark:bg-zinc-900 h-screen w-screen flex">
8-
<is-app-drawer-mini />
7+
<div class="dark:bg-zinc-900 dark:text-zinc-100 font-roboto h-screen w-screen flex">
98
<slot />
109

1110
</div>

packages/app/src/components/IsAppDrawerMini.vue

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ const drawer = ref()
44
<template>
55
<div class="w-14 h-full bg-zinc-800 border-r border-zinc-700 shadow">
66
<div class="flex flex-col h-full">
7-
<is-list-item @click="drawer = !drawer" justify="center" to="/">
7+
<is-list-item justify="center" >
88
<is-logo class="w-5 h-5" />
99
</is-list-item>
1010

1111
<is-tooltip placement="right">
1212
<template #activator="{ attrs }">
1313
<is-list-item
14-
to="/entries"
14+
:to="{ name: 'FileExplorer' }"
1515
justify="center"
1616
v-bind="attrs"
1717
>
@@ -20,25 +20,28 @@ const drawer = ref()
2020
</template>
2121

2222
<div>
23-
{{ $t('entry', 2) }}
23+
{{ $t('fileExplorer') }}
2424
</div>
2525
</is-tooltip>
26-
<!--
26+
2727
<is-tooltip placement="right">
2828
<template #activator="{ attrs }">
2929
<is-list-item
30-
to="/collections"
30+
:to="{ name: 'WorkspaceSelector' }"
3131
justify="center"
3232
v-bind="attrs"
3333
>
34-
<is-icon name="mdi:database" size="xl" />
34+
<is-icon name="fa:cubes" size="xl" />
3535
</is-list-item>
3636
</template>
3737

3838
<div>
39-
{{ $t('collection', 2) }}
39+
{{ $t('workspace', 2) }}
4040
</div>
41-
</is-tooltip> -->
41+
</is-tooltip>
42+
43+
44+
<!--
4245
4346
<is-tooltip placement="right">
4447
<template #activator="{ attrs }">
@@ -88,7 +91,7 @@ const drawer = ref()
8891
<div>
8992
{{ $t('setting', 2) }}
9093
</div>
91-
</is-tooltip>
94+
</is-tooltip> -->
9295
</div>
9396
</div>
9497
</template>

packages/app/src/components/IsBtn.vue

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<script lang="ts" setup>
2+
3+
// general
4+
const classMap = ref(new Map<string, string>())
5+
const classes = computed(() => Array.from(classMap.value.values()).join(' '))
6+
7+
classMap.value.set('general', 'inline-flex items-center justify-center')
8+
9+
// color
10+
const color = defineProp<'accent'>('color', {
11+
type: String,
12+
default: 'accent',
13+
})
14+
15+
function setColor(){
16+
const options = {
17+
accent: 'bg-teal-500',
18+
}
19+
20+
const option = options[color.value]
21+
22+
classMap.value.set('color', option)
23+
}
24+
25+
watch(color, setColor, { immediate: true })
26+
27+
// size
28+
const size = defineProp<'sm' | 'md' | 'lg'>('size', {
29+
type: String,
30+
default: 'md',
31+
})
32+
33+
function setSize(){
34+
const options = {
35+
sm: 'px-2 py-1 text-sm',
36+
md: 'px-4 py-2 text-base',
37+
lg: 'px-6 py-3 text-lg',
38+
}
39+
40+
const option = options[size.value]
41+
42+
classMap.value.set('size', option)
43+
}
44+
45+
watch(size, setSize, { immediate: true })
46+
47+
// rounded
48+
const rounded = defineProp<'sm' | 'md' | 'lg'>('rounded', {
49+
type: String,
50+
default: 'md',
51+
})
52+
53+
function setRounded(){
54+
const options = {
55+
sm: 'rounded-sm',
56+
md: 'rounded-md',
57+
lg: 'rounded-lg',
58+
}
59+
60+
const option = options[rounded.value]
61+
62+
classMap.value.set('rounded', option)
63+
}
64+
65+
watch(rounded, setRounded, { immediate: true })
66+
67+
</script>
68+
69+
<template>
70+
<button :class="classes">
71+
<slot></slot>
72+
</button>
73+
</template>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script lang="ts" setup>
2+
3+
// general
4+
const classMap = ref(new Map<string, string>())
5+
const classes = computed(() => Array.from(classMap.value.values()).join(' '))
6+
7+
classMap.value.set('general', 'p-4')
8+
9+
// color
10+
const color = defineProp<'default'>('color', {
11+
type: String,
12+
default: 'default',
13+
})
14+
15+
function setColor(){
16+
const options = {
17+
default: 'bg-white dark:bg-zinc-800',
18+
}
19+
20+
const option = options[color.value]
21+
22+
classMap.value.set('color', option)
23+
}
24+
25+
watch(color, setColor, { immediate: true })
26+
27+
// rounded
28+
const rounded = defineProp<'sm' | 'md' | 'lg'>('rounded', {
29+
type: String,
30+
default: 'md',
31+
})
32+
33+
function setRounded(){
34+
const options = {
35+
sm: 'rounded-sm',
36+
md: 'rounded-md',
37+
lg: 'rounded-lg',
38+
}
39+
40+
const option = options[rounded.value]
41+
42+
classMap.value.set('rounded', option)
43+
}
44+
45+
watch(rounded, setRounded, { immediate: true })
46+
47+
</script>
48+
49+
<template>
50+
<div :class="classes">
51+
<slot></slot>
52+
</div>
53+
</template>

packages/app/src/components/IsListItem.vue

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const attrs = useAttrs()
99
const classMap = ref(new Map<string, string>())
1010
const classes = computed(() => Array.from(classMap.value.values()).join(' '))
1111
12-
classMap.value.set('base', 'w-full flex items-center')
12+
classMap.value.set('base', 'w-full flex items-center transition-colors')
1313
1414
// size
1515
const size = defineProp<'xs' | 'sm' | 'md' | 'lg' | 'xl'>('size', {
@@ -34,13 +34,19 @@ function setSize(){
3434
watch(size, setSize, { immediate: true })
3535
3636
// color
37-
const color = defineProp<'zinc'>('color', {
37+
const variant = defineProp<'text' | 'fill'>('variant', {
38+
type: String,
39+
default: 'text',
40+
})
41+
42+
const color = defineProp<'zinc' | 'accent'>('color', {
3843
type: String,
3944
default: 'zinc',
4045
})
4146
42-
function setColor(){
47+
function setTextColor(){
4348
const options = {
49+
accent: 'text-teal-500 hover-and-clickable:bg-teal-500 hover-and-clickable:text-teal-500 [&.router-link-active]:bg-teal-500/5',
4450
zinc: 'text-zinc-500 hover-and-clickable:bg-zinc-300/5 hover-and-clickable:text-zinc-300 [&.router-link-active]:bg-zinc-300/5',
4551
}
4652
@@ -49,7 +55,29 @@ function setColor(){
4955
classMap.value.set('color', option)
5056
}
5157
52-
watch(color, setColor, { immediate: true })
58+
function setFillColor(){
59+
const options = {
60+
accent: 'bg-teal-500 hover-and-clickable:bg-teal-400 [&.router-link-active]:bg-teal-400',
61+
zinc: 'bg-zinc-600 hover-and-clickable:bg-zinc-500 [&.router-link-active]:bg-zinc-500',
62+
}
63+
64+
const option = options[color.value]
65+
66+
classMap.value.set('color', option)
67+
}
68+
69+
function setVariant(){
70+
const options = {
71+
text: setTextColor,
72+
fill: setFillColor,
73+
}
74+
75+
const option = options[variant.value]
76+
77+
option()
78+
}
79+
80+
watch([color, variant], setVariant, { immediate: true })
5381
5482
// clickable
5583
const clickable = defineProp<boolean>('clickable', {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
export interface DriveEntry {
3+
path: string
4+
type: 'file'|'directory'
5+
}
6+
7+
export interface Drive {
8+
list: (path: string) => Promise<DriveEntry[]>
9+
read: (path: string) => Promise<string>
10+
write: (path: string, content: any) => Promise<void>
11+
}
12+
13+
const drive = ref<Drive>() as Ref<Drive>
14+
15+
export function useDrive(){
16+
17+
const isLoaded = computed(() => drive.value !== undefined)
18+
19+
function setDrive(newDrive: Drive){
20+
drive.value = newDrive
21+
}
22+
23+
return { drive, isLoaded, setDrive }
24+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Drive, DriveEntry } from "./useDrive";
2+
3+
export function useDriveFileSystemApi(handle: FileSystemDirectoryHandle): Drive {
4+
5+
const list: Drive['list'] = async (path) => {
6+
7+
const result = [] as DriveEntry[]
8+
9+
if (path === '/') {
10+
for await (const entry of handle.values()) {
11+
result.push({
12+
path: entry.name,
13+
type: entry.kind === 'file' ? 'file' : 'directory'
14+
})
15+
}
16+
17+
return result
18+
}
19+
20+
const folder = await handle.getDirectoryHandle(path, {
21+
create: false
22+
})
23+
24+
if (folder.kind !== 'directory') {
25+
throw new Error('Not a directory')
26+
}
27+
28+
const entries = await folder.values()
29+
30+
return entries.map(entry => ({
31+
path: entry.name,
32+
type: entry.kind === 'file' ? 'file' : 'directory'
33+
}))
34+
}
35+
36+
const read: Drive['read'] = async (path) => {
37+
throw new Error('Not implemented')
38+
}
39+
40+
const write: Drive['write'] = async (path, content) => {
41+
throw new Error('Not implemented')
42+
}
43+
44+
return { list, read, write }
45+
}

0 commit comments

Comments
 (0)