@appscode/design-system 2.6.38 → 2.7.1
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/main.scss +2 -0
- package/package.json +1 -1
- package/vue-components/images/banners/banner-background.png +0 -0
- package/vue-components/images/banners/banner-overlay-lg.png +0 -0
- package/vue-components/images/banners/banner-overlay.png +0 -0
- package/vue-components/styles/base/utilities/_spacing.scss +6 -1
- package/vue-components/styles/components/_all.scss +2 -0
- package/vue-components/styles/components/_avatar.scss +11 -0
- package/vue-components/styles/components/_button.scss +15 -0
- package/vue-components/styles/components/_platform-design.scss +188 -0
- package/vue-components/styles/components/form-fields/_file-upload.scss +1 -1
- package/vue-components/styles/components/form-fields/_input.scss +0 -51
- package/vue-components/v3/banner/ProfileBanner.vue +93 -0
- package/vue-components/v3/cards/Cluster.vue +2 -2
- package/vue-components/v3/cards/LinkableThumb.vue +169 -0
- package/vue-components/v3/form-fields/Searchbar.vue +8 -2
- package/vue-components/v3/form-fields/SimpleSelect.vue +3 -1
- package/vue-components/v3/icons/ArrowIcon.vue +0 -1
- package/vue-components/v3/icons/BuildingIcon.vue +13 -0
- package/vue-components/v3/icons/CogIcon.vue +11 -0
- package/vue-components/v3/icons/LinkIcon.vue +13 -0
- package/vue-components/v3/icons/MapIcon.vue +9 -0
- package/vue-components/v3/icons/PlusIcon.vue +13 -0
- package/vue-components/v3/searchbars/FilterableSearchBar.vue +43 -0
- package/vue-components/v3/section/SectionContent.vue +51 -0
- package/vue-components/v3/sidebar/basic-sidebar/DropDownItems.vue +47 -0
- package/vue-components/v3/sidebar/basic-sidebar/Items.vue +22 -0
- package/vue-components/v3/sidebar/basic-sidebar/Sidebar.vue +58 -0
- package/vue-components/v3/table/basic-table/Table.vue +58 -0
package/main.scss
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
// COMPONENTS
|
|
17
17
|
// @import "@/components/vue-components/styles/components/all";
|
|
18
18
|
@import "@/components/vue-components/styles/components/button";
|
|
19
|
+
@import "@/components/vue-components/styles/components/table";
|
|
19
20
|
@import "@/components/vue-components/styles/components/avatar";
|
|
20
21
|
@import "@/components/vue-components/styles/components/terminal";
|
|
21
22
|
@import "@/components/vue-components/styles/components/steps";
|
|
@@ -28,5 +29,6 @@
|
|
|
28
29
|
@import "@/components/vue-components/styles/components/ui-builder/ui-builder";
|
|
29
30
|
@import "@/components/vue-components/styles/components/dropdown";
|
|
30
31
|
@import "@/components/vue-components/styles/components/badge-tags";
|
|
32
|
+
@import "@/components/vue-components/styles/components/platform-design";
|
|
31
33
|
|
|
32
34
|
// @import "@/components/vue-components/styles/theme/appscode.scss";
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -99,7 +99,7 @@ $spacing-values: (
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
/*
|
|
102
|
+
/* Default height & width */
|
|
103
103
|
@for $i from 0 through 300 {
|
|
104
104
|
.height-#{$i} {
|
|
105
105
|
height: #{$i}px !important;
|
|
@@ -108,6 +108,11 @@ $spacing-values: (
|
|
|
108
108
|
.width-#{$i} {
|
|
109
109
|
width: #{$i}px !important;
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
.dimension-#{$i} {
|
|
113
|
+
height: #{$i}px !important;
|
|
114
|
+
width: #{$i}px !important;
|
|
115
|
+
}
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
.height-auto {
|
|
@@ -32,10 +32,12 @@
|
|
|
32
32
|
@import "tfa";
|
|
33
33
|
@import "transitions";
|
|
34
34
|
@import "steps";
|
|
35
|
+
@import "platform-design";
|
|
35
36
|
|
|
36
37
|
// @import "pricing-table";
|
|
37
38
|
// @import "overview-info";
|
|
38
39
|
// @import "overview-page"
|
|
39
40
|
// @import "nested-list";
|
|
41
|
+
|
|
40
42
|
@import "ui-builder/ui-builder";
|
|
41
43
|
@import "ui-builder/vue-open-api";
|
|
@@ -44,6 +44,9 @@
|
|
|
44
44
|
border-color: transparent transparent $ac-primary $ac-primary !important;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
&.is-soft:not(:hover) {
|
|
48
|
+
border-color: hsl(var(--primary-hue), 30%, 80%);
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
&.is-warning {
|
|
@@ -56,6 +59,9 @@
|
|
|
56
59
|
border-color: transparent;
|
|
57
60
|
}
|
|
58
61
|
}
|
|
62
|
+
&.is-soft:not(:hover) {
|
|
63
|
+
border-color: hsl($yellow-hue, 30%, 80%);
|
|
64
|
+
}
|
|
59
65
|
}
|
|
60
66
|
&.is-info {
|
|
61
67
|
&.is-light {
|
|
@@ -67,6 +73,9 @@
|
|
|
67
73
|
border-color: transparent;
|
|
68
74
|
}
|
|
69
75
|
}
|
|
76
|
+
&.is-soft:not(:hover) {
|
|
77
|
+
border-color: hsl($blue-hue, 30%, 80%);
|
|
78
|
+
}
|
|
70
79
|
}
|
|
71
80
|
&.is-danger {
|
|
72
81
|
&.is-light {
|
|
@@ -78,6 +87,9 @@
|
|
|
78
87
|
border-color: transparent;
|
|
79
88
|
}
|
|
80
89
|
}
|
|
90
|
+
&.is-soft:not(:hover) {
|
|
91
|
+
border-color: hsl($red-hue, 30%, 80%);
|
|
92
|
+
}
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
&.is-success {
|
|
@@ -90,6 +102,9 @@
|
|
|
90
102
|
border-color: transparent;
|
|
91
103
|
}
|
|
92
104
|
}
|
|
105
|
+
&.is-soft:not(:hover) {
|
|
106
|
+
border-color: hsl($green-hue, 30%, 80%);
|
|
107
|
+
}
|
|
93
108
|
}
|
|
94
109
|
&.is-light {
|
|
95
110
|
&.is-loading {
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
.profile-banner {
|
|
2
|
+
background-color: #e3f0ea;
|
|
3
|
+
background-image: url("../../images/banners/banner-background.png");
|
|
4
|
+
padding-top: 16px;
|
|
5
|
+
min-height: 120px;
|
|
6
|
+
border-bottom: 1px solid $color-border;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
background-color: #eff9f3;
|
|
9
|
+
position: sticky;
|
|
10
|
+
top: 50px;
|
|
11
|
+
z-index: 999;
|
|
12
|
+
|
|
13
|
+
&::after {
|
|
14
|
+
position: absolute;
|
|
15
|
+
content: "";
|
|
16
|
+
left: 0;
|
|
17
|
+
top: 0;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
background-color: #e7f4ee;
|
|
21
|
+
background-image: url("../../images/banners/banner-overlay.png");
|
|
22
|
+
background-position: 0% 0%;
|
|
23
|
+
backdrop-filter: blur(142px);
|
|
24
|
+
z-index: -1;
|
|
25
|
+
background-repeat: round;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.solid-tab {
|
|
30
|
+
ul {
|
|
31
|
+
border-color: transparent !important;
|
|
32
|
+
}
|
|
33
|
+
li {
|
|
34
|
+
a {
|
|
35
|
+
padding: 16px 0px !important;
|
|
36
|
+
margin-right: 32px;
|
|
37
|
+
transition: 0.3s ease-in-out;
|
|
38
|
+
border-bottom-color: transparent;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.is-active,
|
|
42
|
+
&:hover {
|
|
43
|
+
a {
|
|
44
|
+
border-bottom-color: transparent !important;
|
|
45
|
+
position: relative;
|
|
46
|
+
|
|
47
|
+
&::after {
|
|
48
|
+
position: absolute;
|
|
49
|
+
content: "";
|
|
50
|
+
left: 0;
|
|
51
|
+
bottom: -1px;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 4px;
|
|
54
|
+
border-radius: 4px 4px 0 0;
|
|
55
|
+
z-index: 1;
|
|
56
|
+
background-color: $ac-primary;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.body-bottom {
|
|
64
|
+
.cluster {
|
|
65
|
+
background-color: $primary-light-gray;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.filterable-searchbar {
|
|
70
|
+
width: 100%;
|
|
71
|
+
position: relative;
|
|
72
|
+
|
|
73
|
+
.search-filter {
|
|
74
|
+
border: 1px solid $color-border;
|
|
75
|
+
background-color: #fff;
|
|
76
|
+
position: absolute;
|
|
77
|
+
z-index: 9;
|
|
78
|
+
right: 8px;
|
|
79
|
+
height: 36px;
|
|
80
|
+
top: 8px;
|
|
81
|
+
padding: 8px 16px;
|
|
82
|
+
border-radius: 4px;
|
|
83
|
+
&:focus {
|
|
84
|
+
outline: 1px solid $color-border-dark;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.searchbar {
|
|
89
|
+
width: 100%;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ac-single-input {
|
|
93
|
+
input {
|
|
94
|
+
background-color: $primary-light-gray;
|
|
95
|
+
height: 52px !important;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
label {
|
|
99
|
+
top: 16px !important;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// sidebar items
|
|
105
|
+
.sidebar-style-2 {
|
|
106
|
+
border: 1px solid $color-border;
|
|
107
|
+
border-radius: 4px;
|
|
108
|
+
box-shadow: 8px 4px 14px 0px rgba(0, 0, 0, 0.05);
|
|
109
|
+
|
|
110
|
+
.left-sidebar {
|
|
111
|
+
width: 250px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.sidebar-items {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
|
|
118
|
+
.sidebar-item {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 8px;
|
|
122
|
+
color: $color-text;
|
|
123
|
+
padding: 8px 16px;
|
|
124
|
+
transition: 0.1s ease-in-out;
|
|
125
|
+
|
|
126
|
+
&:last-child {
|
|
127
|
+
margin-bottom: 8px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&:hover {
|
|
131
|
+
background-color: $primary-light-gray;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&.is-active {
|
|
135
|
+
background-color: $ac-primary;
|
|
136
|
+
color: $white-100;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.label {
|
|
141
|
+
border-bottom: 1px solid $color-border;
|
|
142
|
+
font-weight: 400 !important;
|
|
143
|
+
color: $color-heading;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.section-card {
|
|
149
|
+
border: 1px solid $color-border;
|
|
150
|
+
border-radius: 4px;
|
|
151
|
+
.section-heading {
|
|
152
|
+
border-bottom: 1px solid $color-border;
|
|
153
|
+
background-color: $secondary-light-grey;
|
|
154
|
+
padding: 8px 16px;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.more-avatar {
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
justify-content: center;
|
|
162
|
+
width: 24px;
|
|
163
|
+
height: 24px;
|
|
164
|
+
border: 1px solid $color-border;
|
|
165
|
+
border-radius: 50%;
|
|
166
|
+
font-size: 10px;
|
|
167
|
+
padding: 4px;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
background-color: $primary-light-gray;
|
|
170
|
+
}
|
|
171
|
+
.avatar-group {
|
|
172
|
+
display: flex;
|
|
173
|
+
gap: 4px;
|
|
174
|
+
.more-avatar {
|
|
175
|
+
margin-left: -8px;
|
|
176
|
+
z-index: 9;
|
|
177
|
+
}
|
|
178
|
+
.avatar-link {
|
|
179
|
+
display: inline-block;
|
|
180
|
+
&:hover {
|
|
181
|
+
z-index: 9;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
&:not(:first-child) {
|
|
185
|
+
margin-left: -4px;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -578,54 +578,3 @@
|
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
580
|
}
|
|
581
|
-
|
|
582
|
-
// file upload
|
|
583
|
-
.file-upload {
|
|
584
|
-
border: 1px dashed $color-border-dark;
|
|
585
|
-
border-radius: 4px;
|
|
586
|
-
|
|
587
|
-
&:hover {
|
|
588
|
-
background-color: $secondary-light-gray;
|
|
589
|
-
border-color: $ac-primary;
|
|
590
|
-
|
|
591
|
-
label {
|
|
592
|
-
.upload-icon {
|
|
593
|
-
border: 1px solid $color-border-dark;
|
|
594
|
-
|
|
595
|
-
svg {
|
|
596
|
-
color: $color-heading;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
label {
|
|
603
|
-
cursor: pointer;
|
|
604
|
-
padding: 32px;
|
|
605
|
-
display: block;
|
|
606
|
-
|
|
607
|
-
.upload-icon {
|
|
608
|
-
border: 1px solid $color-border;
|
|
609
|
-
display: inline-flex;
|
|
610
|
-
align-items: center;
|
|
611
|
-
justify-content: center;
|
|
612
|
-
border-radius: 50%;
|
|
613
|
-
width: 100px;
|
|
614
|
-
height: 100px;
|
|
615
|
-
margin-bottom: 24px;
|
|
616
|
-
padding: 24px;
|
|
617
|
-
|
|
618
|
-
svg {
|
|
619
|
-
color: $primary-30;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
p {
|
|
624
|
-
color: $color-heading;
|
|
625
|
-
|
|
626
|
-
strong {
|
|
627
|
-
font-weight: 600;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { defineAsyncComponent, defineProps } from "vue";
|
|
3
|
+
import BuildingIcon from "../icons/BuildingIcon.vue";
|
|
4
|
+
import LinkIcon from "../icons/LinkIcon.vue";
|
|
5
|
+
import MapIcon from "../icons/MapIcon.vue";
|
|
6
|
+
|
|
7
|
+
interface TabItemType {
|
|
8
|
+
label: string;
|
|
9
|
+
href: string;
|
|
10
|
+
icon: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PropsType {
|
|
14
|
+
profileThumbnail?: string;
|
|
15
|
+
displayName?: string;
|
|
16
|
+
username?: string;
|
|
17
|
+
location?: string;
|
|
18
|
+
webURL?: string;
|
|
19
|
+
tabs?: TabItemType[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
withDefaults(defineProps<PropsType>(), {
|
|
23
|
+
profileThumbnail: "https://placehold.co/100x100",
|
|
24
|
+
displayName: "John Doe",
|
|
25
|
+
username: "@mohintest1",
|
|
26
|
+
location: "Dhaka",
|
|
27
|
+
webURL: "https://appscode.com",
|
|
28
|
+
tabs: () => [
|
|
29
|
+
{ label: "Overview", href: "#", icon: BuildingIcon },
|
|
30
|
+
{ label: "Organizations", href: "#", icon: BuildingIcon },
|
|
31
|
+
{ label: "Activities", href: "#", icon: BuildingIcon },
|
|
32
|
+
{ label: "Settings", href: "#", icon: BuildingIcon },
|
|
33
|
+
{ label: "Site Administration", href: "#", icon: BuildingIcon },
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Avatar
|
|
38
|
+
const Avatar = defineAsyncComponent(() => import("../avatar/Avatar.vue"));
|
|
39
|
+
// Tabs
|
|
40
|
+
const TabsComponent = defineAsyncComponent(() => import("../tab/Tabs.vue"));
|
|
41
|
+
const TabItemComponent = defineAsyncComponent(() => import("../tab/TabItem.vue"));
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<div class="profile-banner">
|
|
46
|
+
<div class="container">
|
|
47
|
+
<div class="columns is-multiline">
|
|
48
|
+
<div class="column is-12">
|
|
49
|
+
<!-- user profile start -->
|
|
50
|
+
<div class="user-profile">
|
|
51
|
+
<div class="avatar is-flex gap-16">
|
|
52
|
+
<!-- <slot name="avatar"> -->
|
|
53
|
+
<Avatar size="48x48" :imgUrl="profileThumbnail" roundedClass="is-rounded-4" />
|
|
54
|
+
<!-- </slot> -->
|
|
55
|
+
<!-- <Avatar size="48x48" roundedClass="is-rounded-4" /> -->
|
|
56
|
+
<div class="is-flex is-flex-direction-column">
|
|
57
|
+
<h5 class="mb-0">{{ displayName }}</h5>
|
|
58
|
+
<div class="is-flex is-align-items-center gap-24">
|
|
59
|
+
<p>{{ username }}</p>
|
|
60
|
+
<p class="is-flex is-align-items-center gap-4">
|
|
61
|
+
<span class="icon"><MapIcon /></span>
|
|
62
|
+
<span>{{ location }}</span>
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
<a :href="`${webURL}`" target="_blank" class="is-flex is-align-items-center gap-4">
|
|
66
|
+
<span class="icon"><LinkIcon /></span>
|
|
67
|
+
<span class="is-underlined">{{ webURL }}</span>
|
|
68
|
+
</a>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
<!-- user profile start -->
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- <slot name="tabs-menu"> -->
|
|
77
|
+
<!-- tabs area start -->
|
|
78
|
+
<div class="column is-12">
|
|
79
|
+
<tabs-component class="solid-tab px-3">
|
|
80
|
+
<tab-item-component v-for="(tab, index) in tabs" :key="index" :class="{ 'is-active': index === 0 }">
|
|
81
|
+
<a :href="tab.href">
|
|
82
|
+
<span class="icon"><component :is="tab.icon" /></span>
|
|
83
|
+
<span>{{ tab.label }}</span>
|
|
84
|
+
</a>
|
|
85
|
+
</tab-item-component>
|
|
86
|
+
</tabs-component>
|
|
87
|
+
</div>
|
|
88
|
+
<!-- tabs area end -->
|
|
89
|
+
<!-- </slot> -->
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</template>
|
|
@@ -48,8 +48,8 @@ const OptionDots = defineAsyncComponent(() => import("../option-dots/Options.vue
|
|
|
48
48
|
:key="idx + tag.value"
|
|
49
49
|
:class="tag.class"
|
|
50
50
|
:data-testid="idx === 0 ? 'cluster-status-text' : undefined"
|
|
51
|
-
class="is-flex is-align-center gap-
|
|
52
|
-
><span v-if="tag?.isSpinner || false" class="is-flex gap-
|
|
51
|
+
class="is-flex is-align-center gap-6"
|
|
52
|
+
><span v-if="tag?.isSpinner || false" class="is-flex gap-6"><SvgSpinners270Ring /></span
|
|
53
53
|
>{{ tag.value }}</span
|
|
54
54
|
>
|
|
55
55
|
</div>
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Avatar from "../avatar/Avatar.vue";
|
|
3
|
+
|
|
4
|
+
interface RightSidebar {
|
|
5
|
+
title?: string;
|
|
6
|
+
logo?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
viewType?: string;
|
|
9
|
+
members?: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
avatar: string;
|
|
12
|
+
profileUrl: string;
|
|
13
|
+
}>;
|
|
14
|
+
teams?: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
color: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
withDefaults(defineProps<RightSidebar>(), {
|
|
21
|
+
title: "Appscodelabs",
|
|
22
|
+
logo: "https://placehold.co/100x100",
|
|
23
|
+
url: "#",
|
|
24
|
+
viewType: "",
|
|
25
|
+
members: () => [
|
|
26
|
+
{ name: "Alice", avatar: "https://randomuser.me/api/portraits/women/1.jpg", profileUrl: "#" },
|
|
27
|
+
{ name: "Bob", avatar: "https://randomuser.me/api/portraits/men/1.jpg", profileUrl: "#" },
|
|
28
|
+
{ name: "Charlie", avatar: "https://randomuser.me/api/portraits/women/2.jpg", profileUrl: "#" },
|
|
29
|
+
{ name: "Dave", avatar: "https://randomuser.me/api/portraits/men/2.jpg", profileUrl: "#" },
|
|
30
|
+
{ name: "Emma", avatar: "https://randomuser.me/api/portraits/women/3.jpg", profileUrl: "#" },
|
|
31
|
+
{ name: "Frank", avatar: "https://randomuser.me/api/portraits/men/3.jpg", profileUrl: "#" },
|
|
32
|
+
{ name: "Grace", avatar: "https://randomuser.me/api/portraits/women/4.jpg", profileUrl: "#" },
|
|
33
|
+
],
|
|
34
|
+
teams: () => [
|
|
35
|
+
{ name: "Frontend", color: "green" },
|
|
36
|
+
{ name: "Backend", color: "purple" },
|
|
37
|
+
{ name: "UI", color: "green-light" },
|
|
38
|
+
{ name: "Database", color: "blue" },
|
|
39
|
+
{ name: "Socialmedia", color: "gray" },
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<div class="teams-members-container">
|
|
46
|
+
<!-- Organization Thumbnail -->
|
|
47
|
+
<div v-if="viewType === 'organization'" class="org-section">
|
|
48
|
+
<h5>Organizations</h5>
|
|
49
|
+
<ul class="org-list">
|
|
50
|
+
<li v-for="i in 8" :key="i">
|
|
51
|
+
<a :href="url" class="org-thumb" :title="title">
|
|
52
|
+
<img :src="logo" :alt="title" />
|
|
53
|
+
</a>
|
|
54
|
+
</li>
|
|
55
|
+
</ul>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Teams Section -->
|
|
59
|
+
<div v-if="viewType === 'team-member'" class="teams-section">
|
|
60
|
+
<h5>Teams ({{ teams.length }})</h5>
|
|
61
|
+
<div class="teams-list">
|
|
62
|
+
<span v-for="(team, index) in teams" :key="index" :class="['team-tag', team.color]">
|
|
63
|
+
<a :href="url" :title="title" class="team-name">
|
|
64
|
+
{{ team.name }}
|
|
65
|
+
</a>
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<!-- Members Section -->
|
|
71
|
+
<div v-if="viewType === 'team-member'" class="members-section">
|
|
72
|
+
<h5>Members ({{ members.length }})</h5>
|
|
73
|
+
<div class="members-list">
|
|
74
|
+
<a v-for="(member, idx) in members" :key="idx" :href="member.profileUrl" target="_blank" class="member-link">
|
|
75
|
+
<Avatar :rounded="true" size="24x24" :imgUrl="member.avatar" />
|
|
76
|
+
</a>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<style lang="scss">
|
|
83
|
+
.teams-members-container {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
gap: 16px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Organization Thumbnail */
|
|
90
|
+
.org-list {
|
|
91
|
+
display: flex;
|
|
92
|
+
gap: 8px;
|
|
93
|
+
flex-wrap: wrap;
|
|
94
|
+
}
|
|
95
|
+
.org-thumb {
|
|
96
|
+
border: 1px solid $color-border;
|
|
97
|
+
border-radius: 4px;
|
|
98
|
+
padding: 6px;
|
|
99
|
+
height: 48px;
|
|
100
|
+
width: 48px;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
img {
|
|
105
|
+
height: 32px;
|
|
106
|
+
width: auto;
|
|
107
|
+
background-color: #ddd;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Teams Section */
|
|
112
|
+
h5 {
|
|
113
|
+
font-size: 1.1rem;
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.teams-list {
|
|
118
|
+
display: flex;
|
|
119
|
+
flex-wrap: wrap;
|
|
120
|
+
gap: 8px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.team-tag {
|
|
124
|
+
padding: 6px 12px;
|
|
125
|
+
border-radius: 8px;
|
|
126
|
+
font-size: 0.9rem;
|
|
127
|
+
font-weight: 500;
|
|
128
|
+
color: white;
|
|
129
|
+
a {
|
|
130
|
+
color: white;
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Team Colors */
|
|
136
|
+
.green {
|
|
137
|
+
background-color: #28a745;
|
|
138
|
+
}
|
|
139
|
+
.purple {
|
|
140
|
+
background-color: #6f42c1;
|
|
141
|
+
}
|
|
142
|
+
.green-light {
|
|
143
|
+
background-color: #17a2b8;
|
|
144
|
+
}
|
|
145
|
+
.blue {
|
|
146
|
+
background-color: #007bff;
|
|
147
|
+
}
|
|
148
|
+
.gray {
|
|
149
|
+
background-color: #6c757d;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Members Section */
|
|
153
|
+
.members-list {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-wrap: wrap;
|
|
156
|
+
gap: 8px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.member-link {
|
|
160
|
+
text-decoration: none;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.member-avatar {
|
|
164
|
+
width: 40px;
|
|
165
|
+
height: 40px;
|
|
166
|
+
border-radius: 50%;
|
|
167
|
+
object-fit: cover;
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { defineAsyncComponent } from "vue";
|
|
2
|
+
import { defineAsyncComponent, ref, watch } from "vue";
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
5
|
placeholder?: string;
|
|
@@ -13,7 +13,13 @@ withDefaults(defineProps<Props>(), {
|
|
|
13
13
|
loading: false,
|
|
14
14
|
withResult: false,
|
|
15
15
|
});
|
|
16
|
+
const emit = defineEmits(["handleSearch"]);
|
|
16
17
|
|
|
18
|
+
const searchText = ref("");
|
|
19
|
+
|
|
20
|
+
watch(searchText, (n) => {
|
|
21
|
+
emit("handleSearch", n.trim());
|
|
22
|
+
});
|
|
17
23
|
const SearchIcon = defineAsyncComponent(() => import("./../icons/SearchIcon.vue"));
|
|
18
24
|
const RefreshIcon = defineAsyncComponent(() => import("./../icons/RefreshIcon.vue"));
|
|
19
25
|
</script>
|
|
@@ -26,7 +32,7 @@ const RefreshIcon = defineAsyncComponent(() => import("./../icons/RefreshIcon.vu
|
|
|
26
32
|
<SearchIcon v-else />
|
|
27
33
|
</span>
|
|
28
34
|
</label>
|
|
29
|
-
<input id="search" type="text" :placeholder="placeholder" class="pl-40" />
|
|
35
|
+
<input id="search" type="text" :placeholder="placeholder" class="pl-40" v-model="searchText" />
|
|
30
36
|
|
|
31
37
|
<!-- use .is-absolute -->
|
|
32
38
|
<div v-if="withResult" class="search-result-box panel is-fullwidth z-900">
|
|
@@ -15,6 +15,7 @@ interface prop {
|
|
|
15
15
|
options?: Array<Option>;
|
|
16
16
|
isLoading?: boolean;
|
|
17
17
|
optionType?: "simple" | "custom";
|
|
18
|
+
placeholderText?: string;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
const props = withDefaults(defineProps<prop>(), {
|
|
@@ -22,6 +23,7 @@ const props = withDefaults(defineProps<prop>(), {
|
|
|
22
23
|
options: () => [],
|
|
23
24
|
isLoading: false,
|
|
24
25
|
optionType: "simple",
|
|
26
|
+
placeholderText: "Select Option",
|
|
25
27
|
});
|
|
26
28
|
|
|
27
29
|
const emit = defineEmits(["select", "remove", "onRefreshClick"]);
|
|
@@ -88,7 +90,7 @@ watch(isOpen, (n) => {
|
|
|
88
90
|
:style="[isOpen ? { 'z-index': 2 } : '']"
|
|
89
91
|
>
|
|
90
92
|
<label for="custom-select" class="ac-label" :class="{ 'show-label': labelHoisted || isOpen }" @click="selectClick">
|
|
91
|
-
|
|
93
|
+
{{ placeholderText }}
|
|
92
94
|
</label>
|
|
93
95
|
|
|
94
96
|
<input
|
|
@@ -13,7 +13,6 @@ withDefaults(defineProps<{ direction?: "up" | "down" }>(), {
|
|
|
13
13
|
viewBox="0 0 24 24"
|
|
14
14
|
stroke-width="1.5"
|
|
15
15
|
stroke="currentColor"
|
|
16
|
-
class="size-6"
|
|
17
16
|
:style="direction === 'up' ? 'transform: rotate(0deg)' : 'transform: rotate(-180deg)'"
|
|
18
17
|
>
|
|
19
18
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
3
|
+
<!-- Icon from HeroIcons by Refactoring UI Inc - https://github.com/tailwindlabs/heroicons/blob/master/LICENSE -->
|
|
4
|
+
<path
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-linecap="round"
|
|
8
|
+
stroke-linejoin="round"
|
|
9
|
+
stroke-width="1.5"
|
|
10
|
+
d="M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008zm0 3h.008v.008h-.008zm0 3h.008v.008h-.008z"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
3
|
+
<!-- Icon from HeroIcons by Refactoring UI Inc - https://github.com/tailwindlabs/heroicons/blob/master/LICENSE -->
|
|
4
|
+
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
|
5
|
+
<path
|
|
6
|
+
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87q.11.06.22.127c.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a8 8 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a7 7 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a7 7 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a7 7 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124q.108-.066.22-.128c.332-.183.582-.495.644-.869z"
|
|
7
|
+
/>
|
|
8
|
+
<path d="M15 12a3 3 0 1 1-6 0a3 3 0 0 1 6 0" />
|
|
9
|
+
</g>
|
|
10
|
+
</svg>
|
|
11
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
3
|
+
<!-- Icon from HeroIcons by Refactoring UI Inc - https://github.com/tailwindlabs/heroicons/blob/master/LICENSE -->
|
|
4
|
+
<path
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-linecap="round"
|
|
8
|
+
stroke-linejoin="round"
|
|
9
|
+
stroke-width="1.5"
|
|
10
|
+
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
3
|
+
<!-- Icon from HeroIcons by Refactoring UI Inc - https://github.com/tailwindlabs/heroicons/blob/master/LICENSE -->
|
|
4
|
+
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
|
5
|
+
<path d="M15 10.5a3 3 0 1 1-6 0a3 3 0 0 1 6 0" />
|
|
6
|
+
<path d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0" />
|
|
7
|
+
</g>
|
|
8
|
+
</svg>
|
|
9
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
|
|
3
|
+
<!-- Icon from HeroIcons by Refactoring UI Inc - https://github.com/tailwindlabs/heroicons/blob/master/LICENSE -->
|
|
4
|
+
<path
|
|
5
|
+
fill="none"
|
|
6
|
+
stroke="currentColor"
|
|
7
|
+
stroke-linecap="round"
|
|
8
|
+
stroke-linejoin="round"
|
|
9
|
+
stroke-width="1.5"
|
|
10
|
+
d="M12 4.5v15m7.5-7.5h-15"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { defineAsyncComponent, defineProps, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
placeholder: {
|
|
5
|
+
type: String,
|
|
6
|
+
default: "Search what you are looking for...",
|
|
7
|
+
},
|
|
8
|
+
isFilter: {
|
|
9
|
+
type: Boolean,
|
|
10
|
+
default: false,
|
|
11
|
+
},
|
|
12
|
+
filterOptions: {
|
|
13
|
+
type: Array,
|
|
14
|
+
default: () => [
|
|
15
|
+
{ value: "all-cluster", text: "All Cluster" },
|
|
16
|
+
{ value: "active", text: "Active" },
|
|
17
|
+
{ value: "pending", text: "Pending" },
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
const emit = defineEmits(["handleSearch", "handleFilter"]);
|
|
22
|
+
function handleSearch(searchText) {
|
|
23
|
+
emit("handleSearch", searchText);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const selectedFilter = ref("all-cluster");
|
|
27
|
+
|
|
28
|
+
watch(selectedFilter, (n) => {
|
|
29
|
+
emit("handleFilter", n);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const Searchbar = defineAsyncComponent(() => import("../form-fields/Searchbar.vue"));
|
|
33
|
+
</script>
|
|
34
|
+
<template>
|
|
35
|
+
<div class="filterable-searchbar is-flex">
|
|
36
|
+
<Searchbar :placeholder="props.placeholder" @handleSearch="handleSearch" />
|
|
37
|
+
<select class="select search-filter" v-show="props.isFilter" v-model="selectedFilter">
|
|
38
|
+
<option v-for="option in filterOptions" :key="option.value" :value="option.value">
|
|
39
|
+
{{ option.text }}
|
|
40
|
+
</option>
|
|
41
|
+
</select>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import ArrowIcon from "../icons/ArrowIcon.vue";
|
|
4
|
+
import AcButton from "../button/Button.vue";
|
|
5
|
+
import HeaderItem from "../header/HeaderItem.vue";
|
|
6
|
+
import HeaderItems from "../header/HeaderItems.vue";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
title?: string;
|
|
10
|
+
isExpandable?: boolean;
|
|
11
|
+
custom?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
withDefaults(defineProps<Props>(), {
|
|
15
|
+
title: "",
|
|
16
|
+
isExpandable: false,
|
|
17
|
+
custom: false,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const isOpen = ref(true);
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<div class="content-body">
|
|
25
|
+
<div class="section-card is-fullwidth">
|
|
26
|
+
<div class="section-heading is-fullwidth is-flex is-align-items-center is-justify-content-space-between">
|
|
27
|
+
<header-items>
|
|
28
|
+
<header-item>
|
|
29
|
+
<div v-if="custom">
|
|
30
|
+
<slot name="custom-header" />
|
|
31
|
+
</div>
|
|
32
|
+
<div v-else>
|
|
33
|
+
<h4 :key="title">{{ title }}</h4>
|
|
34
|
+
</div>
|
|
35
|
+
</header-item>
|
|
36
|
+
</header-items>
|
|
37
|
+
<!-- Add buttons here -->
|
|
38
|
+
<div class="buttons is-right">
|
|
39
|
+
<slot name="header-buttons" />
|
|
40
|
+
<AcButton modifier-classes="is-white" v-if="isExpandable" @click="isOpen = !isOpen">
|
|
41
|
+
<ArrowIcon :direction="isOpen ? 'down' : 'up'" />
|
|
42
|
+
</AcButton>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div v-show="isOpen" class="section-body">
|
|
47
|
+
<slot name="section-body" />
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, watch } from "vue";
|
|
3
|
+
import HeroiconsChevronDown20Solid from "~icons/heroicons/chevron-down-20-solid";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
title: string;
|
|
7
|
+
isOpen?: boolean;
|
|
8
|
+
hasIcon?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
12
|
+
isOpen: false,
|
|
13
|
+
hasIcon: false,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const dropDownStatus = ref<"close" | "open">("close");
|
|
17
|
+
|
|
18
|
+
const toggleDropDownStatus = () => {
|
|
19
|
+
if (dropDownStatus.value === "open") dropDownStatus.value = "close";
|
|
20
|
+
else dropDownStatus.value = "open";
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
watch(
|
|
24
|
+
() => props.isOpen,
|
|
25
|
+
(n) => {
|
|
26
|
+
if (n) {
|
|
27
|
+
dropDownStatus.value = "open";
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{ immediate: true },
|
|
31
|
+
);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<div
|
|
36
|
+
class="label pt-10 pb-10 pl-16 pr-16 b-b-1 is-flex is-align-items-center is-justify-content-space-between is-fullwidth is-clickable"
|
|
37
|
+
@click="toggleDropDownStatus"
|
|
38
|
+
>
|
|
39
|
+
<div class="is-flex gap-8">
|
|
40
|
+
<span v-if="hasIcon" class="icon"> <slot name="drop-down-icon" /> </span>{{ title }}
|
|
41
|
+
</div>
|
|
42
|
+
<HeroiconsChevronDown20Solid
|
|
43
|
+
:style="{ transform: dropDownStatus === 'open' ? 'rotate(180deg)' : 'none', transition: '0.2s' }"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
<slot v-if="dropDownStatus === 'open'" name="drop-down-items" />
|
|
47
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
id: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
withDefaults(defineProps<Props>(), {
|
|
10
|
+
isActive: false,
|
|
11
|
+
url: "",
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div class="sidebar-item is-clickable" :class="{ 'is-active': isActive }">
|
|
17
|
+
<span class="icon">
|
|
18
|
+
<slot name="item-icon" />
|
|
19
|
+
</span>
|
|
20
|
+
<span>{{ title }}</span>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts"></script>
|
|
2
|
+
|
|
3
|
+
<template>
|
|
4
|
+
<div class="sidebar-style-2">
|
|
5
|
+
<div class="left-sidebar">
|
|
6
|
+
<div class="sidebar-items">
|
|
7
|
+
<slot name="items-with-drop-down" />
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<style lang="scss" scoped>
|
|
14
|
+
.sidebar-style-2 {
|
|
15
|
+
border: 1px solid $color-border;
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
box-shadow: 8px 4px 14px 0px rgba(0, 0, 0, 0.05);
|
|
18
|
+
|
|
19
|
+
.left-sidebar {
|
|
20
|
+
width: 250px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.sidebar-items {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
|
|
27
|
+
.sidebar-item {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 8px;
|
|
31
|
+
color: $color-text;
|
|
32
|
+
padding: 8px 16px;
|
|
33
|
+
transition: 0.1s ease-in-out;
|
|
34
|
+
|
|
35
|
+
&:last-child {
|
|
36
|
+
margin-bottom: 8px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&:hover {
|
|
40
|
+
background-color: $primary-light-gray;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.is-active {
|
|
44
|
+
background-color: $ac-primary;
|
|
45
|
+
color: $white-100;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
label {
|
|
50
|
+
padding: 8px 16px;
|
|
51
|
+
border-bottom: 1px solid $color-border;
|
|
52
|
+
text-transform: uppercase;
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
color: #616161;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Avatar from "../../avatar/Avatar.vue";
|
|
3
|
+
|
|
4
|
+
interface Organization {
|
|
5
|
+
name: string;
|
|
6
|
+
logo: string;
|
|
7
|
+
description: string;
|
|
8
|
+
clusters: number;
|
|
9
|
+
members: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
avatar: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
defineProps<{ organizations: Organization[] }>();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<table class="table ac-table is-fullwidth b-1 is-middle">
|
|
20
|
+
<thead>
|
|
21
|
+
<tr>
|
|
22
|
+
<th>Organizations</th>
|
|
23
|
+
<th class="has-text-right">Clusters</th>
|
|
24
|
+
<th class="has-text-right">Members</th>
|
|
25
|
+
</tr>
|
|
26
|
+
</thead>
|
|
27
|
+
|
|
28
|
+
<tbody>
|
|
29
|
+
<tr v-for="(org, index) in organizations" :key="index" class="is-clickable">
|
|
30
|
+
<td>
|
|
31
|
+
<div class="is-flex gap-8">
|
|
32
|
+
<div class="org-thumb">
|
|
33
|
+
<img :src="org.logo" :alt="org.name" />
|
|
34
|
+
</div>
|
|
35
|
+
<div class="is-flex is-flex-direction-column">
|
|
36
|
+
<h5>{{ org.name }}</h5>
|
|
37
|
+
<p>{{ org.description }}</p>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</td>
|
|
41
|
+
|
|
42
|
+
<td class="has-text-right">{{ org.clusters }}</td>
|
|
43
|
+
<td class="has-text-right">
|
|
44
|
+
<div class="is-flex is-justify-content-flex-end avatar-group">
|
|
45
|
+
<Avatar
|
|
46
|
+
v-for="(member, idx) in org.members"
|
|
47
|
+
:key="idx"
|
|
48
|
+
:rounded="true"
|
|
49
|
+
size="24x24"
|
|
50
|
+
:src="member.avatar"
|
|
51
|
+
:alt="member.name"
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
</td>
|
|
55
|
+
</tr>
|
|
56
|
+
</tbody>
|
|
57
|
+
</table>
|
|
58
|
+
</template>
|