sprintify-ui 0.0.19 → 0.0.21
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/dist/sprintify-ui.es.js +6877 -4264
- package/dist/types/src/components/BaseActionItem.vue.d.ts +121 -0
- package/dist/types/src/components/BaseAlert.vue.d.ts +3 -3
- package/dist/types/src/components/BaseAppDialogs.vue.d.ts +1 -1
- package/dist/types/src/components/BaseBoolean.vue.d.ts +2 -2
- package/dist/types/src/components/BaseCounter.vue.d.ts +3 -3
- package/dist/types/src/components/BaseDialog.vue.d.ts +4 -4
- package/dist/types/src/components/BaseInput.vue.d.ts +1 -1
- package/dist/types/src/components/BaseLayoutNotificationDropdown.vue.d.ts +24 -0
- package/dist/types/src/components/BaseLayoutNotificationItem.vue.d.ts +14 -0
- package/dist/types/src/components/BaseLayoutSidebar.vue.d.ts +114 -0
- package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +182 -0
- package/dist/types/src/components/BaseLayoutStacked.vue.d.ts +76 -0
- package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +182 -0
- package/dist/types/src/components/BaseMenu.vue.d.ts +17 -15
- package/dist/types/src/components/BaseMenuItem.vue.d.ts +5 -5
- package/dist/types/src/components/BaseNavbar.vue.d.ts +20 -1
- package/dist/types/src/components/BaseNavbarItem.vue.d.ts +17 -71
- package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +11 -2
- package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +26 -0
- package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +50 -0
- package/dist/types/src/components/BaseSwitch.vue.d.ts +3 -3
- package/dist/types/src/components/BaseSystemAlert.vue.d.ts +8 -8
- package/dist/types/src/components/BaseTableColumn.vue.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +6 -1
- package/dist/types/src/index.d.ts +12 -0
- package/dist/types/src/types/Notification.d.ts +8 -0
- package/dist/types/src/types/types.d.ts +9 -0
- package/package.json +6 -3
- package/src/components/BaseActionItem.vue +68 -0
- package/src/components/{HasMany.stories.js → BaseHasMany.stories.js} +0 -0
- package/src/components/BaseLayoutNotificationDropdown.vue +101 -0
- package/src/components/BaseLayoutNotificationItem.vue +58 -0
- package/src/components/BaseLayoutSidebar.vue +199 -0
- package/src/components/BaseLayoutSidebarConfigurable.stories.js +129 -0
- package/src/components/BaseLayoutSidebarConfigurable.vue +118 -0
- package/src/components/BaseLayoutStacked.vue +52 -0
- package/src/components/BaseLayoutStackedConfigurable.stories.js +110 -0
- package/src/components/BaseLayoutStackedConfigurable.vue +129 -0
- package/src/components/BaseMediaItem.vue +7 -7
- package/src/components/BaseMediaLibrary.vue +3 -3
- package/src/components/BaseMediaPreview.vue +1 -1
- package/src/components/BaseMenu.vue +12 -4
- package/src/components/BaseNavbar.stories.js +18 -14
- package/src/components/BaseNavbar.vue +19 -3
- package/src/components/BaseNavbarItem.vue +17 -43
- package/src/components/BaseNavbarItemContent.vue +36 -16
- package/src/components/BaseNavbarSideItem.vue +42 -0
- package/src/components/BaseNavbarSideItemContent.vue +77 -0
- package/src/components/index.ts +11 -0
- package/src/lang/en.json +3 -0
- package/src/lang/fr.json +3 -0
- package/src/types/Notification.ts +10 -0
- package/src/types/types.ts +11 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import BaseContainer from './BaseContainer.vue';
|
|
2
|
+
import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Layout/BaseLayoutSidebarConfigurable',
|
|
6
|
+
component: BaseLayoutSidebarConfigurable,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'fullscreen',
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
user: {
|
|
12
|
+
email: 'jane@witify.io',
|
|
13
|
+
first_name: 'Jane',
|
|
14
|
+
last_name: 'Doe',
|
|
15
|
+
full_name: 'Jane Doe',
|
|
16
|
+
avatar_url:
|
|
17
|
+
'https://images.unsplash.com/photo-1494790108377-be9c29b29330??auto=format&fit=crop&w=200&h=200&q=80&g=face',
|
|
18
|
+
},
|
|
19
|
+
menu: [
|
|
20
|
+
{
|
|
21
|
+
title: 'General',
|
|
22
|
+
actions: [
|
|
23
|
+
{
|
|
24
|
+
label: 'Dashboard',
|
|
25
|
+
to: '/',
|
|
26
|
+
icon: 'heroicons-home',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: 'Articles',
|
|
30
|
+
to: '/articles',
|
|
31
|
+
icon: 'heroicons:document-text',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'Users',
|
|
35
|
+
to: '/users',
|
|
36
|
+
icon: 'heroicons:users',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: 'Settings',
|
|
42
|
+
actions: [
|
|
43
|
+
{
|
|
44
|
+
label: 'Account',
|
|
45
|
+
to: '/account',
|
|
46
|
+
icon: 'heroicons:cog',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: 'Logout',
|
|
50
|
+
action: logout,
|
|
51
|
+
icon: 'heroicons:arrow-left-on-rectangle',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
userMenu: [
|
|
57
|
+
{
|
|
58
|
+
label: 'Dashboard',
|
|
59
|
+
to: '/',
|
|
60
|
+
icon: 'heroicons-home',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: 'Settings',
|
|
64
|
+
to: '/account',
|
|
65
|
+
icon: 'heroicons:cog',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
label: 'Logout',
|
|
69
|
+
action: logout,
|
|
70
|
+
icon: 'heroicons:arrow-left-on-rectangle',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
notifications: {
|
|
74
|
+
footerTo: '/',
|
|
75
|
+
footerLabel: 'See all notifications',
|
|
76
|
+
items: [
|
|
77
|
+
{
|
|
78
|
+
id: '1',
|
|
79
|
+
text: 'You have a new message',
|
|
80
|
+
to: '/',
|
|
81
|
+
created_at: '2022-01-01T00:00:00',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: '2',
|
|
85
|
+
text: 'Your inbox is now full. Please empty your inbox before it goes bang.',
|
|
86
|
+
to: '/',
|
|
87
|
+
created_at: '2022-01-01T00:00:00',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
async function logout() {
|
|
95
|
+
alert('logout');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const Template = (args) => ({
|
|
99
|
+
components: {
|
|
100
|
+
BaseContainer,
|
|
101
|
+
BaseLayoutSidebarConfigurable,
|
|
102
|
+
},
|
|
103
|
+
setup() {
|
|
104
|
+
return { args };
|
|
105
|
+
},
|
|
106
|
+
template: `
|
|
107
|
+
<BaseLayoutSidebarConfigurable v-bind="args">
|
|
108
|
+
<div class="py-16">
|
|
109
|
+
<BaseContainer size="3xl">
|
|
110
|
+
<p v-for="i in 20" class="mb-1">
|
|
111
|
+
Amet occaecat enim pariatur incididunt enim laborum enim. Duis cillum in in excepteur sit excepteur laboris consectetur magna. Commodo proident labore commodo duis veniam do nisi irure ipsum officia excepteur non. Nisi cillum mollit tempor ut.
|
|
112
|
+
</p>
|
|
113
|
+
</BaseContainer>
|
|
114
|
+
</div>
|
|
115
|
+
</BaseLayoutSidebarConfigurable>
|
|
116
|
+
`,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export const Light = Template.bind({});
|
|
120
|
+
Light.args = {
|
|
121
|
+
dark: false,
|
|
122
|
+
logoUrl: 'https://sprintify.witify.io/img/logo/logo-side.svg',
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const Dark = Template.bind({});
|
|
126
|
+
Dark.args = {
|
|
127
|
+
dark: true,
|
|
128
|
+
logoUrl: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
|
|
129
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<BaseLayoutSidebar :app-name="appName" :logo-url="logoUrl" :dark="dark">
|
|
3
|
+
<template #menu>
|
|
4
|
+
<div class="px-3 py-6">
|
|
5
|
+
<div class="space-y-8">
|
|
6
|
+
<div v-for="section in actionSections" :key="section.title">
|
|
7
|
+
<h2
|
|
8
|
+
v-if="section.title"
|
|
9
|
+
class="mb-3 pl-3 text-xs font-semibold uppercase tracking-widest"
|
|
10
|
+
:class="dark ? 'text-slate-400' : 'text-slate-500'"
|
|
11
|
+
>
|
|
12
|
+
{{ section.title }}
|
|
13
|
+
</h2>
|
|
14
|
+
<div>
|
|
15
|
+
<div class="space-y-1">
|
|
16
|
+
<BaseNavbarSideItem
|
|
17
|
+
v-for="item in section.actions"
|
|
18
|
+
:key="item.label"
|
|
19
|
+
:item="item"
|
|
20
|
+
:dark="dark"
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<template #navbar>
|
|
30
|
+
<div class="flex flex-1 justify-between px-4">
|
|
31
|
+
<div class="flex flex-1">
|
|
32
|
+
<!-- Good spot for search bar... -->
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="ml-4 flex items-center md:ml-6">
|
|
36
|
+
<!-- Notification dropdown -->
|
|
37
|
+
<BaseLayoutNotificationDropdown
|
|
38
|
+
v-if="notifications"
|
|
39
|
+
:notifications-config="notifications"
|
|
40
|
+
class="mr-1 sm:mr-2"
|
|
41
|
+
></BaseLayoutNotificationDropdown>
|
|
42
|
+
|
|
43
|
+
<!-- Profile dropdown -->
|
|
44
|
+
<div class="relative ml-3 mr-3">
|
|
45
|
+
<BaseMenu :items="userMenu">
|
|
46
|
+
<template #button="{ open }">
|
|
47
|
+
<div class="flex" :class="[open ? '' : '']">
|
|
48
|
+
<BaseAvatar :user="user" show-details />
|
|
49
|
+
</div>
|
|
50
|
+
</template>
|
|
51
|
+
</BaseMenu>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<template #default>
|
|
58
|
+
<slot />
|
|
59
|
+
</template>
|
|
60
|
+
</BaseLayoutSidebar>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script setup lang="ts">
|
|
64
|
+
import { User } from '@/types/User';
|
|
65
|
+
import { PropType } from 'vue';
|
|
66
|
+
import { ActionItem, ActionSection, NotificationsConfig } from '../types/types';
|
|
67
|
+
import BaseAvatar from './BaseAvatar.vue';
|
|
68
|
+
import BaseLayoutNotificationDropdown from './BaseLayoutNotificationDropdown.vue';
|
|
69
|
+
import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
|
|
70
|
+
import BaseMenu from './BaseMenu.vue';
|
|
71
|
+
import BaseNavbarSideItem from './BaseNavbarSideItem.vue';
|
|
72
|
+
|
|
73
|
+
const props = defineProps({
|
|
74
|
+
appName: {
|
|
75
|
+
default: '',
|
|
76
|
+
type: String,
|
|
77
|
+
},
|
|
78
|
+
logoUrl: {
|
|
79
|
+
default: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
|
|
80
|
+
type: String,
|
|
81
|
+
},
|
|
82
|
+
menu: {
|
|
83
|
+
required: true,
|
|
84
|
+
type: Array as PropType<ActionItem[] | ActionSection[]>,
|
|
85
|
+
},
|
|
86
|
+
userMenu: {
|
|
87
|
+
required: true,
|
|
88
|
+
type: Array as PropType<ActionItem[]>,
|
|
89
|
+
},
|
|
90
|
+
user: {
|
|
91
|
+
required: true,
|
|
92
|
+
type: Object as PropType<User>,
|
|
93
|
+
},
|
|
94
|
+
notifications: {
|
|
95
|
+
default: undefined,
|
|
96
|
+
type: Object as PropType<NotificationsConfig>,
|
|
97
|
+
},
|
|
98
|
+
dark: {
|
|
99
|
+
default: false,
|
|
100
|
+
type: Boolean,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const actionSections = computed((): ActionSection[] => {
|
|
105
|
+
const isActionSections = props.menu.length > 0 && 'actions' in props.menu[0];
|
|
106
|
+
|
|
107
|
+
if (isActionSections) {
|
|
108
|
+
return props.menu as ActionSection[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
title: '',
|
|
114
|
+
actions: props.menu as ActionItem[],
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
});
|
|
118
|
+
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="sticky top-0 z-20 w-full shadow-sm">
|
|
3
|
+
<BaseSystemAlert
|
|
4
|
+
v-for="systemAlert in systemAlerts"
|
|
5
|
+
:key="systemAlert.id"
|
|
6
|
+
:color="systemAlert.color"
|
|
7
|
+
:to="systemAlert.to"
|
|
8
|
+
:action="systemAlert.action"
|
|
9
|
+
:closable="systemAlert.closable"
|
|
10
|
+
@close="systemAlertStore.remove(systemAlert)"
|
|
11
|
+
>
|
|
12
|
+
{{ systemAlert.message }}
|
|
13
|
+
</BaseSystemAlert>
|
|
14
|
+
|
|
15
|
+
<BaseNavbar :dark="dark">
|
|
16
|
+
<template #navbar>
|
|
17
|
+
<slot name="navbar" />
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<template #mobile>
|
|
21
|
+
<slot name="mobile" />
|
|
22
|
+
</template>
|
|
23
|
+
</BaseNavbar>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div>
|
|
27
|
+
<slot />
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts" setup>
|
|
32
|
+
import { useSystemAlertStore } from '../stores/systemAlerts';
|
|
33
|
+
import BaseNavbar from './BaseNavbar.vue';
|
|
34
|
+
import BaseSystemAlert from './BaseSystemAlert.vue';
|
|
35
|
+
|
|
36
|
+
defineProps({
|
|
37
|
+
dark: {
|
|
38
|
+
default: false,
|
|
39
|
+
type: Boolean,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* System Alerts
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
const systemAlertStore = useSystemAlertStore();
|
|
48
|
+
|
|
49
|
+
const systemAlerts = computed(() => {
|
|
50
|
+
return systemAlertStore.systemAlerts;
|
|
51
|
+
});
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import BaseContainer from './BaseContainer.vue';
|
|
2
|
+
import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Layout/BaseLayoutStackedConfigurable',
|
|
6
|
+
component: BaseLayoutStackedConfigurable,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'fullscreen',
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
appName: 'Sprintify',
|
|
12
|
+
user: {
|
|
13
|
+
email: 'jane@witify.io',
|
|
14
|
+
first_name: 'Jane',
|
|
15
|
+
last_name: 'Doe',
|
|
16
|
+
full_name: 'Jane Doe',
|
|
17
|
+
avatar_url:
|
|
18
|
+
'https://images.unsplash.com/photo-1494790108377-be9c29b29330??auto=format&fit=crop&w=200&h=200&q=80&g=face',
|
|
19
|
+
},
|
|
20
|
+
menu: [
|
|
21
|
+
{
|
|
22
|
+
label: 'Products',
|
|
23
|
+
to: '/',
|
|
24
|
+
count: 234,
|
|
25
|
+
type: 'RouterLink',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Users',
|
|
29
|
+
to: '/setup',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Account',
|
|
33
|
+
to: '/settings',
|
|
34
|
+
icon: 'heroicons:cog',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
userMenu: [
|
|
38
|
+
{
|
|
39
|
+
label: 'Dashboard',
|
|
40
|
+
to: '/',
|
|
41
|
+
icon: 'heroicons-home',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: 'Settings',
|
|
45
|
+
to: '/account',
|
|
46
|
+
icon: 'heroicons:cog',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: 'Logout',
|
|
50
|
+
action: logout,
|
|
51
|
+
icon: 'heroicons:arrow-left-on-rectangle',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
notifications: {
|
|
55
|
+
footerTo: '/',
|
|
56
|
+
footerLabel: 'See all notifications',
|
|
57
|
+
items: [
|
|
58
|
+
{
|
|
59
|
+
id: '1',
|
|
60
|
+
text: 'You have a new message',
|
|
61
|
+
to: '/',
|
|
62
|
+
created_at: '2022-12-08T19:16:10Z',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: '2',
|
|
66
|
+
text: 'Your inbox is now full. Please empty your inbox before it goes bang.',
|
|
67
|
+
to: '/',
|
|
68
|
+
created_at: '2022-01-01T00:00:00',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
async function logout() {
|
|
76
|
+
alert('logout');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const Template = (args) => ({
|
|
80
|
+
components: {
|
|
81
|
+
BaseLayoutStackedConfigurable,
|
|
82
|
+
BaseContainer,
|
|
83
|
+
},
|
|
84
|
+
setup() {
|
|
85
|
+
return { args };
|
|
86
|
+
},
|
|
87
|
+
template: `
|
|
88
|
+
<BaseLayoutStackedConfigurable v-bind="args">
|
|
89
|
+
<div class="py-16">
|
|
90
|
+
<BaseContainer size="3xl">
|
|
91
|
+
<p v-for="i in 20" class="mb-1">
|
|
92
|
+
Amet occaecat enim pariatur incididunt enim laborum enim. Duis cillum in in excepteur sit excepteur laboris consectetur magna. Commodo proident labore commodo duis veniam do nisi irure ipsum officia excepteur non. Nisi cillum mollit tempor ut.
|
|
93
|
+
</p>
|
|
94
|
+
</BaseContainer>
|
|
95
|
+
</div>
|
|
96
|
+
</BaseLayoutStackedConfigurable>
|
|
97
|
+
`,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export const Light = Template.bind({});
|
|
101
|
+
Light.args = {
|
|
102
|
+
dark: false,
|
|
103
|
+
logoUrl: 'https://sprintify.witify.io/img/logo/logo-side.svg',
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const Dark = Template.bind({});
|
|
107
|
+
Dark.args = {
|
|
108
|
+
dark: true,
|
|
109
|
+
logoUrl: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
|
|
110
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<BaseLayoutStacked :dark="dark">
|
|
3
|
+
<template #navbar>
|
|
4
|
+
<div class="flex h-16 justify-between">
|
|
5
|
+
<!-- Left -->
|
|
6
|
+
|
|
7
|
+
<div class="flex justify-center">
|
|
8
|
+
<!-- Logo -->
|
|
9
|
+
<router-link to="/" class="flex flex-shrink-0 items-center p-2 pl-0">
|
|
10
|
+
<img class="block h-8 w-auto" :src="logoUrl" :alt="appName" />
|
|
11
|
+
</router-link>
|
|
12
|
+
|
|
13
|
+
<!-- Links (desktop) -->
|
|
14
|
+
<div class="ml-10 hidden space-x-4 md:flex">
|
|
15
|
+
<BaseNavbarItem
|
|
16
|
+
v-for="item in menu"
|
|
17
|
+
:key="item.label"
|
|
18
|
+
:item="item"
|
|
19
|
+
:dark="dark"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<!-- Right -->
|
|
25
|
+
<div class="flex items-center md:ml-6">
|
|
26
|
+
<!-- Notification dropdown -->
|
|
27
|
+
<BaseLayoutNotificationDropdown
|
|
28
|
+
v-if="notifications"
|
|
29
|
+
class="mr-4 md:mr-5"
|
|
30
|
+
:dark="dark"
|
|
31
|
+
:notifications-config="notifications"
|
|
32
|
+
></BaseLayoutNotificationDropdown>
|
|
33
|
+
|
|
34
|
+
<!-- Profile dropdown -->
|
|
35
|
+
<BaseMenu menu-class="w-52" class="hidden md:block" :items="userMenu">
|
|
36
|
+
<template #button="{ open }">
|
|
37
|
+
<div class="flex rounded-full" :class="[open ? '' : '']">
|
|
38
|
+
<BaseAvatar :class="dark ? 'text-white' : ''" :user="user" />
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
</BaseMenu>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<template #mobile>
|
|
47
|
+
<!-- Links mobile -->
|
|
48
|
+
<div class="space-y-1 p-2 pt-0">
|
|
49
|
+
<BaseNavbarSideItem
|
|
50
|
+
v-for="item in menu"
|
|
51
|
+
:key="item.label"
|
|
52
|
+
:item="item"
|
|
53
|
+
:dark="dark"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<hr
|
|
58
|
+
class="mb-4 mt-2"
|
|
59
|
+
:class="[dark ? 'border-slate-700' : 'border-slate-200']"
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
<!-- Profile links -->
|
|
63
|
+
<div class="p-2 pb-6">
|
|
64
|
+
<BaseAvatar
|
|
65
|
+
:user="user"
|
|
66
|
+
show-details
|
|
67
|
+
size="base"
|
|
68
|
+
class="px-3"
|
|
69
|
+
:class="dark ? 'text-white' : ''"
|
|
70
|
+
/>
|
|
71
|
+
<div class="mt-4 space-y-1">
|
|
72
|
+
<BaseNavbarSideItem
|
|
73
|
+
v-for="item in userMenu"
|
|
74
|
+
:key="item.label"
|
|
75
|
+
:item="item"
|
|
76
|
+
:dark="dark"
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<template #default>
|
|
83
|
+
<slot name="default" />
|
|
84
|
+
</template>
|
|
85
|
+
</BaseLayoutStacked>
|
|
86
|
+
</template>
|
|
87
|
+
|
|
88
|
+
<script lang="ts" setup>
|
|
89
|
+
import { User } from '@/types/User';
|
|
90
|
+
import { PropType } from 'vue';
|
|
91
|
+
import { ActionItem, NotificationsConfig } from '../types/types';
|
|
92
|
+
import BaseAvatar from './BaseAvatar.vue';
|
|
93
|
+
import BaseLayoutStacked from './BaseLayoutStacked.vue';
|
|
94
|
+
import BaseMenu from './BaseMenu.vue';
|
|
95
|
+
import BaseNavbarItem from './BaseNavbarItem.vue';
|
|
96
|
+
import BaseNavbarSideItem from './BaseNavbarSideItem.vue';
|
|
97
|
+
import BaseLayoutNotificationDropdown from './BaseLayoutNotificationDropdown.vue';
|
|
98
|
+
|
|
99
|
+
defineProps({
|
|
100
|
+
appName: {
|
|
101
|
+
default: '',
|
|
102
|
+
type: String,
|
|
103
|
+
},
|
|
104
|
+
logoUrl: {
|
|
105
|
+
default: 'https://sprintify.witify.io/img/logo/logo-side.svg',
|
|
106
|
+
type: String,
|
|
107
|
+
},
|
|
108
|
+
menu: {
|
|
109
|
+
required: true,
|
|
110
|
+
type: Array as PropType<ActionItem[]>,
|
|
111
|
+
},
|
|
112
|
+
userMenu: {
|
|
113
|
+
required: true,
|
|
114
|
+
type: Array as PropType<ActionItem[]>,
|
|
115
|
+
},
|
|
116
|
+
user: {
|
|
117
|
+
required: true,
|
|
118
|
+
type: Object as PropType<User>,
|
|
119
|
+
},
|
|
120
|
+
notifications: {
|
|
121
|
+
default: undefined,
|
|
122
|
+
type: Object as PropType<NotificationsConfig>,
|
|
123
|
+
},
|
|
124
|
+
dark: {
|
|
125
|
+
default: false,
|
|
126
|
+
type: Boolean,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
</script>
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="rounded
|
|
2
|
+
<div class="rounded bg-white shadow">
|
|
3
3
|
<div class="relative flex">
|
|
4
4
|
<div class="shrink-0">
|
|
5
|
-
<BaseMediaPreview class="h-
|
|
5
|
+
<BaseMediaPreview class="h-12 w-12 rounded-l" :media="media" />
|
|
6
6
|
</div>
|
|
7
7
|
<component
|
|
8
8
|
:is="url ? 'a' : 'p'"
|
|
9
9
|
:href="url"
|
|
10
10
|
target="_blank"
|
|
11
|
-
class="grow overflow-hidden px-3
|
|
11
|
+
class="flex grow items-center overflow-hidden px-3"
|
|
12
12
|
>
|
|
13
13
|
<div class="text-left leading-tight">
|
|
14
|
-
<p class="grow truncate text-
|
|
14
|
+
<p class="mb-px grow truncate text-[13px] font-medium">
|
|
15
15
|
{{ name }}
|
|
16
16
|
</p>
|
|
17
|
-
<p class="shrink-0 text-[10px]
|
|
17
|
+
<p class="shrink-0 text-[10px] text-slate-400">
|
|
18
18
|
{{ size }}
|
|
19
19
|
</p>
|
|
20
20
|
</div>
|
|
21
21
|
</component>
|
|
22
|
-
<div v-if="showRemove" class="shrink-0 p-
|
|
22
|
+
<div v-if="showRemove" class="shrink-0 p-0.5">
|
|
23
23
|
<button
|
|
24
24
|
type="button"
|
|
25
|
-
class="rounded-full bg-
|
|
25
|
+
class="rounded-full bg-white p-1 text-slate-400 hover:bg-slate-100"
|
|
26
26
|
@click="$emit('remove')"
|
|
27
27
|
>
|
|
28
28
|
<BaseIcon icon="heroicons:x-mark-20-solid" class="h-4 w-4"></BaseIcon>
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
<div
|
|
23
23
|
class="rounded border border-dashed p-6 duration-150"
|
|
24
24
|
:class="[
|
|
25
|
-
baseFileUploaderProps.dragging ? 'bg-blue-100' : 'bg-
|
|
25
|
+
baseFileUploaderProps.dragging ? 'bg-blue-100' : 'bg-white',
|
|
26
26
|
baseFileUploaderProps.disabled
|
|
27
27
|
? 'cursor-not-allowed border-slate-300'
|
|
28
|
-
: 'border-slate-300 hover:bg-slate-
|
|
28
|
+
: 'border-slate-300 hover:bg-slate-100',
|
|
29
29
|
]"
|
|
30
30
|
>
|
|
31
31
|
<div :class="[baseFileUploaderProps.disabled ? 'opacity-30' : '']">
|
|
32
32
|
<BaseIcon
|
|
33
33
|
icon="heroicons:arrow-up-on-square"
|
|
34
|
-
class="mx-auto mb-3 h-6 w-6 text-
|
|
34
|
+
class="mx-auto mb-3 h-6 w-6 text-slate-500"
|
|
35
35
|
/>
|
|
36
36
|
<div class="text-center">
|
|
37
37
|
<p class="mb-0 text-sm font-medium leading-tight">
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Menu
|
|
2
|
+
<Menu
|
|
3
|
+
v-slot="{ open }"
|
|
4
|
+
as="div"
|
|
5
|
+
class="text-left"
|
|
6
|
+
:class="[position == 'custom' ? 'static' : 'relative']"
|
|
7
|
+
>
|
|
3
8
|
<div>
|
|
4
9
|
<MenuButton class="flex">
|
|
5
10
|
<slot name="button" :open="open" />
|
|
@@ -18,7 +23,7 @@
|
|
|
18
23
|
:class="[menuClass, menuPositionClass]"
|
|
19
24
|
class="absolute z-menu mt-2 rounded-md bg-white p-1 shadow-lg ring-1 ring-black ring-opacity-10 focus:outline-none"
|
|
20
25
|
>
|
|
21
|
-
<slot name="items">
|
|
26
|
+
<slot name="items" :items="items">
|
|
22
27
|
<template v-for="item in items" :key="item.label + 'link'">
|
|
23
28
|
<div v-if="item.line" class="my-1 -mx-1 flex h-px bg-gray-200" />
|
|
24
29
|
|
|
@@ -95,15 +100,18 @@ const props = defineProps({
|
|
|
95
100
|
},
|
|
96
101
|
menuClass: {
|
|
97
102
|
default: 'w-48',
|
|
98
|
-
type: String,
|
|
103
|
+
type: [String, Array, Object],
|
|
99
104
|
},
|
|
100
105
|
position: {
|
|
101
106
|
default: 'bottom-left',
|
|
102
|
-
type: String as PropType<'bottom-left' | 'bottom-right'>,
|
|
107
|
+
type: String as PropType<'bottom-left' | 'bottom-right' | 'custom'>,
|
|
103
108
|
},
|
|
104
109
|
});
|
|
105
110
|
|
|
106
111
|
const menuPositionClass = computed(() => {
|
|
112
|
+
if (props.position == 'custom') {
|
|
113
|
+
return '';
|
|
114
|
+
}
|
|
107
115
|
if (props.position == 'bottom-left') {
|
|
108
116
|
return 'origin-top-right right-0';
|
|
109
117
|
}
|