@edgedev/create-edge-app 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/app.vue CHANGED
@@ -9,7 +9,4 @@
9
9
 
10
10
  <style lang="scss">
11
11
  .firebase-emulator-warning { display: none; }
12
- html, body {
13
- overflow: hidden;
14
- }
15
12
  </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/create-edge-app",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Create Edge Starter App",
5
5
  "bin": {
6
6
  "create-edge-app": "./bin/cli.js"
@@ -40,36 +40,33 @@ const menuItems = [
40
40
  </script>
41
41
 
42
42
  <template>
43
- <NuxtLayout name="app">
44
- <div
45
- v-if="edgeGlobal.edgeState.organizationDocPath"
46
- class="flex-1 flex flex-col overflow-y-auto p-3 pt-0"
47
- >
48
- <div class="h-full p-0">
49
- <SidebarProvider class="min-h-full">
50
- <div class="h-full md:w-[180px]">
51
- <edge-side-bar
52
- :menu-items="menuItems"
53
- :settings-menu-items="isAdmin ? adminMenuItems : []"
54
- collapsible="submenu"
55
- class="bg-background text-foreground border-none w-[180px] absolute shadow-none"
56
- :show-settings-section="false"
57
- title="My Settings"
58
- settings-title="Organization Settings"
59
- group-label-classes="text-foreground/70"
60
- >
61
- <template #header>
62
- <h1 class="text-xl">
63
- Settings
64
- </h1>
65
- </template>
66
- </edge-side-bar>
67
- </div>
68
- <NuxtPage class="flex-1 flex flex-col overflow-y-auto p-3" />
69
- </SidebarProvider>
70
- </div>
43
+ <div
44
+ v-if="edgeGlobal.edgeState.organizationDocPath"
45
+ >
46
+ <div class="h-full p-0">
47
+ <SidebarProvider class="min-h-full">
48
+ <div class="h-full md:w-[180px]">
49
+ <edge-side-bar
50
+ :menu-items="menuItems"
51
+ :settings-menu-items="isAdmin ? adminMenuItems : []"
52
+ collapsible="submenu"
53
+ class="bg-background text-foreground border-none w-[180px] absolute shadow-none"
54
+ :show-settings-section="false"
55
+ title="My Settings"
56
+ settings-title="Organization Settings"
57
+ group-label-classes="text-foreground/70"
58
+ >
59
+ <template #header>
60
+ <h1 class="text-xl">
61
+ Settings
62
+ </h1>
63
+ </template>
64
+ </edge-side-bar>
65
+ </div>
66
+ <NuxtPage class="flex-1 flex flex-col overflow-y-auto p-3" />
67
+ </SidebarProvider>
71
68
  </div>
72
- </NuxtLayout>
69
+ </div>
73
70
  </template>
74
71
 
75
72
  <style lang="scss">
@@ -71,69 +71,90 @@ onMounted(() => {
71
71
  </script>
72
72
 
73
73
  <template>
74
- <NuxtLayout name="app">
75
- <div
76
- v-if="edgeGlobal.edgeState.organizationDocPath"
77
- class="flex-1 flex flex-col overflow-y-auto p-3 pt-0"
78
- >
79
- <edge-dashboard v-if="docId === ''" :filter="state.filter" :collection="collection" class="flex-1">
80
- <template #header-start>
81
- <LayoutDashboard class="mr-2" />
82
- <span class="capitalize">{{ collection }}</span>
83
- </template>
84
- <template #header-center>
85
- <div class="w-full px-6">
86
- <edge-shad-input
87
- v-model="state.filter"
88
- label=""
89
- name="filter"
90
- placeholder="Filter..."
91
- />
74
+ <div
75
+ v-if="edgeGlobal.edgeState.organizationDocPath"
76
+ >
77
+ <edge-dashboard v-if="docId === ''" :filter="state.filter" :collection="collection" class="flex-1">
78
+ <template #header-start>
79
+ <LayoutDashboard class="mr-2" />
80
+ <span class="capitalize">{{ collection }}</span>
81
+ </template>
82
+ <template #header-center>
83
+ <div class="w-full px-6">
84
+ <edge-shad-input
85
+ v-model="state.filter"
86
+ label=""
87
+ name="filter"
88
+ placeholder="Filter..."
89
+ />
90
+ </div>
91
+ </template>
92
+ <template #header-end="slotProps">
93
+ <edge-shad-button class="uppercase bg-slate-600" :to="`/app/dashboard/${collection}/new`">
94
+ Add {{ slotProps.title }}
95
+ </edge-shad-button>
96
+ </template>
97
+ <template #list-item="slotProps">
98
+ <edge-shad-button variant="text" class="cursor-pointer w-full flex justify-between slotProps.items-center py-2 gap-3" :to="`/app/dashboard/${collection}/${slotProps.item.docId}`">
99
+ <div>
100
+ <Avatar class="cursor-pointer p-0 h-8 w-8 mr-2">
101
+ <FilePenLine class="h-5 w-5" />
102
+ </Avatar>
92
103
  </div>
93
- </template>
94
- <template #header-end="slotProps">
95
- <edge-shad-button class="uppercase bg-slate-600" :to="`/app/dashboard/${collection}/new`">
96
- Add {{ slotProps.title }}
97
- </edge-shad-button>
98
- </template>
99
- <template #list-item="slotProps">
100
- <edge-shad-button variant="text" class="cursor-pointer w-full flex justify-between slotProps.items-center py-2 gap-3" :to="`/app/dashboard/${collection}/${slotProps.item.docId}`">
101
- <div>
102
- <Avatar class="cursor-pointer p-0 h-8 w-8 mr-2">
103
- <FilePenLine class="h-5 w-5" />
104
- </Avatar>
105
- </div>
106
- <div class="grow text-left">
107
- <div class="text-lg">
108
- {{ slotProps.item.name }}
109
- </div>
104
+ <div class="grow text-left">
105
+ <div class="text-lg">
106
+ {{ slotProps.item.name }}
110
107
  </div>
111
- <div>
112
- <edge-shad-button
113
- size="icon"
114
- class="bg-slate-600 h-7 w-7"
115
- @click.stop="slotProps.deleteItem(slotProps.item.docId)"
116
- >
117
- <Trash class="h-5 w-5" />
118
- </edge-shad-button>
119
- </div>
120
- </edge-shad-button>
121
- <Separator class="dark:bg-slate-600" />
122
- </template>
123
- </edge-dashboard>
124
- <edge-editor
125
- v-else
126
- :collection="collection"
127
- :doc-id="docId"
128
- :schema="schemas[collection]"
129
- :new-doc-schema="state.newDocs[collection]"
130
- class="w-full max-w-7xl mx-auto flex-1"
131
- >
132
- <template #header-start="slotProps">
133
- <FilePenLine class="mr-2" />
134
- {{ slotProps.title }}
135
- </template>
136
- <template #header-end="slotProps">
108
+ </div>
109
+ <div>
110
+ <edge-shad-button
111
+ size="icon"
112
+ class="bg-slate-600 h-7 w-7"
113
+ @click.stop="slotProps.deleteItem(slotProps.item.docId)"
114
+ >
115
+ <Trash class="h-5 w-5" />
116
+ </edge-shad-button>
117
+ </div>
118
+ </edge-shad-button>
119
+ <Separator class="dark:bg-slate-600" />
120
+ </template>
121
+ </edge-dashboard>
122
+ <edge-editor
123
+ v-else
124
+ :collection="collection"
125
+ :doc-id="docId"
126
+ :schema="schemas[collection]"
127
+ :new-doc-schema="state.newDocs[collection]"
128
+ class="w-full max-w-7xl mx-auto flex-1"
129
+ >
130
+ <template #header-start="slotProps">
131
+ <FilePenLine class="mr-2" />
132
+ {{ slotProps.title }}
133
+ </template>
134
+ <template #header-end="slotProps">
135
+ <edge-shad-button
136
+ v-if="!slotProps.unsavedChanges"
137
+ :to="`/app/dashboard/${collection}`"
138
+ class="bg-red-700 uppercase h-8 hover:bg-slate-400 w-20"
139
+ >
140
+ Close
141
+ </edge-shad-button>
142
+ <edge-shad-button
143
+ v-else
144
+ :to="`/app/dashboard/${collection}`"
145
+ class="bg-red-700 uppercase h-8 hover:bg-slate-400 w-20"
146
+ >
147
+ Cancel
148
+ </edge-shad-button>
149
+ <edge-shad-button
150
+ type="submit"
151
+ class="bg-slate-500 uppercase h-8 hover:bg-slate-400 w-20"
152
+ >
153
+ Save
154
+ </edge-shad-button>
155
+ </template>
156
+ <template #footer="slotProps">
157
+ <div class="flex w-full gap-1 items-center justify-end">
137
158
  <edge-shad-button
138
159
  v-if="!slotProps.unsavedChanges"
139
160
  :to="`/app/dashboard/${collection}`"
@@ -148,39 +169,15 @@ onMounted(() => {
148
169
  >
149
170
  Cancel
150
171
  </edge-shad-button>
172
+
151
173
  <edge-shad-button
152
174
  type="submit"
153
175
  class="bg-slate-500 uppercase h-8 hover:bg-slate-400 w-20"
154
176
  >
155
177
  Save
156
178
  </edge-shad-button>
157
- </template>
158
- <template #footer="slotProps">
159
- <div class="flex w-full gap-1 items-center justify-end">
160
- <edge-shad-button
161
- v-if="!slotProps.unsavedChanges"
162
- :to="`/app/dashboard/${collection}`"
163
- class="bg-red-700 uppercase h-8 hover:bg-slate-400 w-20"
164
- >
165
- Close
166
- </edge-shad-button>
167
- <edge-shad-button
168
- v-else
169
- :to="`/app/dashboard/${collection}`"
170
- class="bg-red-700 uppercase h-8 hover:bg-slate-400 w-20"
171
- >
172
- Cancel
173
- </edge-shad-button>
174
-
175
- <edge-shad-button
176
- type="submit"
177
- class="bg-slate-500 uppercase h-8 hover:bg-slate-400 w-20"
178
- >
179
- Save
180
- </edge-shad-button>
181
- </div>
182
- </template>
183
- </edge-editor>
184
- </div>
185
- </NuxtLayout>
179
+ </div>
180
+ </template>
181
+ </edge-editor>
182
+ </div>
186
183
  </template>
@@ -2,17 +2,15 @@
2
2
  </script>
3
3
 
4
4
  <template>
5
- <NuxtLayout name="app">
6
- <div class="flex w-full h-full align-center items-center">
7
- <edge-auth type="login" class="p-8 mx-auto max-w-lg w-full h-full max-h-[540px] overflow-y-auto">
8
- <div class="grid gap-2 text-center">
9
- <h1 class="text-2xl font-bold">
10
- Login
11
- </h1>
12
- </div>
13
- </edge-auth>
14
- </div>
15
- </NuxtLayout>
5
+ <div class="flex w-full h-full align-center items-center">
6
+ <edge-auth type="login" class="p-8 mx-auto max-w-lg w-full h-full max-h-[540px] overflow-y-auto">
7
+ <div class="grid gap-2 text-center">
8
+ <h1 class="text-2xl font-bold">
9
+ Login
10
+ </h1>
11
+ </div>
12
+ </edge-auth>
13
+ </div>
16
14
  </template>
17
15
 
18
16
  <style lang="scss" scoped>
@@ -3,17 +3,15 @@ const config = useRuntimeConfig()
3
3
  </script>
4
4
 
5
5
  <template>
6
- <NuxtLayout name="app">
7
- <div class="flex w-full h-full align-center items-center">
8
- <edge-auth type="register" :registration-code="config.public.registrationCode" class="p-8 mx-auto max-w-lg w-full h-full max-h-[760px] overflow-y-auto">
9
- <div class="grid gap-2 text-center">
10
- <h1 class="text-2xl font-bold">
11
- Sign Up
12
- </h1>
13
- </div>
14
- </edge-auth>
15
- </div>
16
- </NuxtLayout>
6
+ <div class="flex w-full h-full align-center items-center">
7
+ <edge-auth type="register" :registration-code="config.public.registrationCode" class="p-8 mx-auto max-w-lg w-full h-full max-h-[760px] overflow-y-auto">
8
+ <div class="grid gap-2 text-center">
9
+ <h1 class="text-2xl font-bold">
10
+ Sign Up
11
+ </h1>
12
+ </div>
13
+ </edge-auth>
14
+ </div>
17
15
  </template>
18
16
 
19
17
  <style lang="scss" scoped>
package/pages/app.vue ADDED
@@ -0,0 +1,256 @@
1
+ <script setup>
2
+ const edgeFirebase = inject('edgeFirebase')
3
+ // const edgeGlobal = inject('edgeGlobal')
4
+
5
+ const route = useRoute()
6
+
7
+ const currentOrganization = computed(() => {
8
+ return edgeGlobal.edgeState.currentOrganization
9
+ })
10
+
11
+ watch(currentOrganization, async () => {
12
+ if (currentOrganization.value) {
13
+ // RUN STUFF HERE WHEN ORGANIZATION CHANGES LIKE SNAPSHOTS
14
+ await projectSetOrg(currentOrganization.value, edgeFirebase, edgeGlobal)
15
+
16
+ // KEEP THIS CODE:
17
+ const auth = useState('auth')
18
+ auth.value = edgeFirebase.user
19
+
20
+ const preLoginRoute = useState('preLoginRoute')
21
+ const router = useRouter()
22
+
23
+ let cleanedRoute = ''
24
+ if (preLoginRoute.value) {
25
+ cleanedRoute = preLoginRoute.value.endsWith('/') ? preLoginRoute.value.slice(0, -1) : preLoginRoute.value
26
+ }
27
+
28
+ if (cleanedRoute === ''
29
+ || cleanedRoute === '/app'
30
+ || cleanedRoute === '/app/login'
31
+ || cleanedRoute === '/app/signup') {
32
+ router.push('/app/dashboard')
33
+ }
34
+ else {
35
+ router.push(preLoginRoute.value)
36
+ }
37
+
38
+ console.log(auth.value)
39
+ }
40
+ if (!currentOrganization.value) {
41
+ const auth = useState('auth')
42
+ auth.value = ''
43
+ const router = useRouter()
44
+ router.push('/app/login')
45
+ }
46
+ })
47
+
48
+ const currentOrg = computed(() => edgeFirebase.data[`organizations/${edgeGlobal.edgeState.currentOrganization}`])
49
+
50
+ watch (currentOrg, async () => {
51
+ if (currentOrg.value) {
52
+ edgeGlobal.edgeState = subscribedStatus(currentOrg.value)
53
+ }
54
+ }, { immediate: true }, { deep: true })
55
+
56
+ const orgName = computed(() => {
57
+ const org = edgeGlobal.edgeState.organizations.find(org => org.docId === edgeGlobal.edgeState.currentOrganization)
58
+ return org?.name
59
+ })
60
+
61
+ const user = computed(() => {
62
+ return edgeFirebase.user
63
+ })
64
+
65
+ watch (user, async () => {
66
+ if (user.value) {
67
+ const auth = useState('auth')
68
+ auth.value = user.value
69
+ }
70
+ })
71
+ const colorMode = useColorMode()
72
+ onMounted(() => {
73
+ colorMode.preference = 'system'
74
+ })
75
+
76
+ const showLeftPanel = computed(() => {
77
+ return edgeGlobal?.edgeState?.showLeftPanel[route.path]
78
+ })
79
+
80
+ const leftPanelDefaultSize = computed(() => {
81
+ if (showLeftPanel.value) {
82
+ return 20
83
+ }
84
+ return 0
85
+ })
86
+
87
+ const mainPanelDefaultSize = computed(() => {
88
+ if (showLeftPanel.value) {
89
+ return 80
90
+ }
91
+ return 100
92
+ })
93
+
94
+ const leftPanel = ref(null)
95
+ const mainPanel = ref(null)
96
+
97
+ watch(showLeftPanel, (value) => {
98
+ if (leftPanel.value && mainPanel.value) {
99
+ const animateResize = (panel, targetSize) => {
100
+ let currentSize = panel.value.getSize()
101
+ const step = (targetSize - currentSize) / 10 // Smooth out the transition
102
+
103
+ const animate = () => {
104
+ if (Math.abs(currentSize - targetSize) > 0.5) {
105
+ currentSize += step
106
+ panel.value.resize(currentSize)
107
+ requestAnimationFrame(animate)
108
+ }
109
+ else {
110
+ panel.value.resize(targetSize)
111
+ }
112
+ }
113
+
114
+ animate()
115
+ }
116
+
117
+ if (value) {
118
+ animateResize(leftPanel, 20)
119
+ animateResize(mainPanel, 80)
120
+ }
121
+ else {
122
+ animateResize(leftPanel, 0)
123
+ animateResize(mainPanel, 100)
124
+ }
125
+ }
126
+ })
127
+
128
+ edgeFirebase.runFunction('edgeFirebase-initFirestore', {})
129
+ edgeGlobal.edgeState.userRoles = [
130
+ {
131
+ name: 'Admin',
132
+ roles: [
133
+ {
134
+ collectionPath: 'organizationDocPath',
135
+ role: 'admin',
136
+ },
137
+ ],
138
+ },
139
+ {
140
+ name: 'User',
141
+ roles: [
142
+ {
143
+ collectionPath: 'organizationDocPath',
144
+ role: 'user',
145
+ },
146
+ ],
147
+ },
148
+ ]
149
+
150
+ const menuItems = [
151
+ {
152
+ title: 'Dashboard',
153
+ to: '/app/dashboard/things',
154
+ icon: 'LayoutDashboard',
155
+ },
156
+ {
157
+ title: 'Sub Things',
158
+ to: '/app/dashboard/subthings',
159
+ icon: 'Package',
160
+ },
161
+ ]
162
+ </script>
163
+
164
+ <template>
165
+ <Head>
166
+ <title>Edge App</title>
167
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
168
+ </Head>
169
+ <Toaster />
170
+ <div class="flex flex-col h-[calc(100vh+200px)]">
171
+ <div class="flex h-full w-full fixed">
172
+ <edge-sidebar-provider
173
+ v-slot="sideBarProviderProps"
174
+ enable-nested-menu
175
+ collapsible="slack"
176
+ >
177
+ <div class="h-full">
178
+ <edge-side-bar
179
+ v-if="edgeFirebase.user.loggedIn"
180
+ :menu-items="menuItems"
181
+ :collapsible="sideBarProviderProps.collapsible"
182
+ class="border-solid border-r"
183
+ >
184
+ <template #header>
185
+ <SidebarMenu>
186
+ <SidebarMenuItem>
187
+ <SidebarMenuButton style="padding-left: 4px !important;">
188
+ <Package class="!h-6 !w-6" /> <span class="text-xl">{{ orgName }}</span>
189
+ </SidebarMenuButton>
190
+ </SidebarMenuItem>
191
+ </SidebarMenu>
192
+ </template>
193
+ <template #footer="slotProps">
194
+ <Card v-if="slotProps.sideBarState === 'expanded'">
195
+ <CardHeader class="p-2 pt-0 md:p-4">
196
+ <CardTitle>Upgrade to Pro</CardTitle>
197
+ <CardDescription>
198
+ Unlock all features and get unlimited access to our support
199
+ team.
200
+ </CardDescription>
201
+ </CardHeader>
202
+ <CardContent class="p-2 pt-0 md:p-4 md:pt-0">
203
+ <Button size="sm" class="w-full">
204
+ Upgrade
205
+ </Button>
206
+ </CardContent>
207
+ </Card>
208
+ </template>
209
+ </edge-side-bar>
210
+ </div>
211
+ <ResizablePanelGroup
212
+ direction="horizontal"
213
+ class="h-full w-full"
214
+ >
215
+ <ResizablePanel ref="leftPanel" class="bg-sidebar text-sidebar-foreground" :default-size="leftPanelDefaultSize">
216
+ <div id="left-panel" />
217
+ </ResizablePanel>
218
+ <ResizableHandle v-if="showLeftPanel" with-handle />
219
+ <ResizablePanel ref="mainPanel" :default-size="mainPanelDefaultSize">
220
+ <div class="grow h-full flex flex-col h-screen">
221
+ <edge-menu
222
+ v-if="edgeFirebase.user.loggedIn"
223
+ type="nav"
224
+ nav-class="justify-left"
225
+ class="px-1 border-none"
226
+ >
227
+ <template #start>
228
+ <edge-shad-button
229
+ v-show="edgeGlobal.edgeState.sidebar.isMobile"
230
+ variant="icon"
231
+ class="p-1"
232
+ @click="edgeGlobal.edgeState.sidebar.toggleSidebar"
233
+ >
234
+ <MenuSquare />
235
+ </edge-shad-button>
236
+ </template>
237
+ </edge-menu>
238
+ <NuxtPage class="flex-1 flex flex-col overflow-y-auto p-3 pt-0" />
239
+ </div>
240
+ </ResizablePanel>
241
+ </ResizablePanelGroup>
242
+ </edge-sidebar-provider>
243
+ </div>
244
+ </div>
245
+ </template>
246
+
247
+ <style lang="scss">
248
+ .firebase-emulator-warning { display: none; }
249
+ html {
250
+ scrollbar-width: none;
251
+ }
252
+
253
+ html::-webkit-scrollbar {
254
+ display: none;
255
+ }
256
+ </style>