@appscode/design-system 1.0.43-alpha.13 → 1.0.43-alpha.132

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.
Files changed (104) hide show
  1. package/base/utilities/_default.scss +283 -21
  2. package/base/utilities/_derived-variables.scss +0 -13
  3. package/base/utilities/_initial-variables.scss +78 -56
  4. package/base/utilities/_mixin.scss +10 -17
  5. package/base/utilities/_typography.scss +23 -7
  6. package/base/utilities/dark-theme.scss +25 -0
  7. package/components/_ac-accordion.scss +1 -0
  8. package/components/_ac-alert-box.scss +18 -10
  9. package/components/_ac-card.scss +55 -20
  10. package/components/_ac-code-highlight.scss +7 -1
  11. package/components/_ac-content-layout.scss +4 -4
  12. package/components/_ac-drag.scss +6 -6
  13. package/components/_ac-input.scss +74 -40
  14. package/components/_ac-modal.scss +5 -4
  15. package/components/_ac-multi-select.scss +195 -13
  16. package/components/_ac-options.scss +31 -16
  17. package/components/_ac-select-box.scss +15 -5
  18. package/components/_ac-table.scss +42 -36
  19. package/components/_ac-tabs.scss +72 -23
  20. package/components/_ac-tags.scss +2 -2
  21. package/components/_ac-terminal.scss +272 -0
  22. package/components/_app-drawer.scss +6 -6
  23. package/components/_breadcumb.scss +7 -2
  24. package/components/_buttons.scss +60 -27
  25. package/components/_card-body-wrapper.scss +3 -3
  26. package/components/_dashboard-header.scss +33 -1
  27. package/components/_direct-deploy.scss +69 -0
  28. package/components/_go-to-top.scss +1 -1
  29. package/components/_graph.scss +45 -0
  30. package/components/_image-upload.scss +6 -4
  31. package/components/_left-sidebar-menu.scss +200 -46
  32. package/components/_monaco-editor.scss +1 -1
  33. package/components/_navbar.scss +129 -26
  34. package/components/_overview-info.scss +4 -4
  35. package/components/_overview-page.scss +1 -2
  36. package/components/_pagination.scss +10 -2
  37. package/components/_payment-card.scss +28 -12
  38. package/components/_preview-modal.scss +19 -8
  39. package/components/_pricing-table.scss +1 -1
  40. package/components/_progress-bar.scss +5 -5
  41. package/components/_subscription-card.scss +15 -8
  42. package/components/_table-of-content.scss +1 -1
  43. package/components/_tfa.scss +69 -0
  44. package/components/_transitions.scss +261 -0
  45. package/components/_widget-menu.scss +9 -9
  46. package/components/_wizard.scss +31 -19
  47. package/components/ac-toaster/_ac-toasted.scss +5 -5
  48. package/components/bbum/_card-team.scss +18 -10
  49. package/components/bbum/_information-center.scss +17 -3
  50. package/components/bbum/_mobile-desktop.scss +6 -6
  51. package/components/bbum/_post.scss +5 -4
  52. package/components/bbum/_sign-up-notification.scss +6 -6
  53. package/components/bbum/_single-post-preview.scss +9 -9
  54. package/components/bbum/_user-profile.scss +97 -90
  55. package/components/ui-builder/_ui-builder.scss +29 -10
  56. package/components/ui-builder/_vue-open-api.scss +98 -0
  57. package/layouts/_404.scss +2 -1
  58. package/layouts/_code-preview.scss +14 -7
  59. package/main.scss +4 -0
  60. package/package.json +2 -7
  61. package/plugins/theme.js +130 -128
  62. package/vue-components/v2/banner/Banner.vue +2 -2
  63. package/vue-components/v2/breadcrumbs/Breadcrumb.vue +97 -0
  64. package/vue-components/v2/button/Button.vue +5 -0
  65. package/vue-components/v2/button/DownloadBtn.vue +45 -0
  66. package/vue-components/v2/card/PaymentCards.vue +11 -2
  67. package/vue-components/v2/content/ContentTable.vue +12 -7
  68. package/vue-components/v2/editor/Editor.vue +29 -1
  69. package/vue-components/v2/editor/FilteredFileEditor.vue +153 -0
  70. package/vue-components/v2/editor/ResourceKeyValueEditor.vue +196 -0
  71. package/vue-components/v2/loaders/ResourceLoader.vue +90 -0
  72. package/vue-components/v2/loaders/SidebarLoader.vue +32 -0
  73. package/vue-components/v2/modal/Modal.vue +33 -12
  74. package/vue-components/v2/modals/DeleteConfirmationModal.vue +77 -0
  75. package/vue-components/v2/modals/JsonShowModal.vue +12 -2
  76. package/vue-components/v2/navbar/Appdrawer.vue +10 -9
  77. package/vue-components/v2/navbar/ThemeMode.vue +120 -0
  78. package/vue-components/v2/navbar/User.vue +154 -12
  79. package/vue-components/v2/preloader/Preloader.vue +5 -5
  80. package/vue-components/v2/sidebar/ClusterSwitcher.vue +126 -0
  81. package/vue-components/v2/sidebar/SidebarItem.vue +23 -1
  82. package/vue-components/v2/sidebar/SidebarItemWithDropDown.vue +19 -20
  83. package/vue-components/v2/table/Table.vue +43 -8
  84. package/vue-components/v2/table/TableRow.vue +17 -8
  85. package/vue-components/v2/table/table-cell/CellValue.vue +31 -4
  86. package/vue-components/v2/table/table-cell/GenericCell.vue +56 -0
  87. package/vue-components/v2/table/table-cell/ObjectCell.vue +4 -1
  88. package/vue-components/v2/tabs/EditorTabs.vue +1 -1
  89. package/vue-components/v3/button/Button.vue +5 -0
  90. package/vue-components/v3/dropdown/DropdownMenu.vue +1 -1
  91. package/vue-components/v3/editor/Editor.vue +32 -11
  92. package/vue-components/v3/modal/Modal.vue +10 -1
  93. package/vue-components/v3/modals/JsonShowModal.vue +13 -4
  94. package/vue-components/v3/navbar/Appdrawer.vue +12 -7
  95. package/vue-components/v3/navbar/ThemeMode.vue +128 -0
  96. package/vue-components/v3/navbar/User.vue +154 -12
  97. package/vue-components/v3/sidebar/ClusterSwitcher.vue +133 -0
  98. package/vue-components/v3/sidebar/SidebarItemWithDropDown.vue +120 -0
  99. package/vue-components/v3/table/Table.vue +27 -5
  100. package/vue-components/v3/table/TableRow.vue +1 -1
  101. package/vue-components/v3/table/table-cell/CellValue.vue +26 -3
  102. package/vue-components/v3/table/table-cell/GenericCell.vue +62 -0
  103. package/vue-components/v3/table/table-cell/ObjectCell.vue +5 -1
  104. package/vue-components/v3/tabs/EditorTabs.vue +1 -1
@@ -7,7 +7,7 @@
7
7
  <img :src="user.avatar_url" alt="User Photo" />
8
8
  </div>
9
9
  </button>
10
- <navbar-item-content>
10
+ <navbar-item-content class="navbar-dropdown-wrapper">
11
11
  <div v-if="user.username" class="user-profile-wrapper">
12
12
  <div class="profile-area">
13
13
  <div class="profile-photo">
@@ -15,23 +15,98 @@
15
15
  <button class="camera-icon"></button>
16
16
  </div>
17
17
  <div class="profile-info">
18
- <p>{{ user.username.toUpperCase() }}</p>
18
+ <p :title="user.username.toUpperCase()" class="is-ellipsis-1">{{ user.username.toUpperCase() }}</p>
19
19
  <a :href="`mailto:${user.email}`"> {{ user.email }}</a>
20
20
  </div>
21
21
  </div>
22
- <ul>
23
- <li>
22
+ <transition-group name="list" tag="ul">
23
+ <li key="settings">
24
24
  <a :href="`${serverDomain}/user/settings/`">Settings</a>
25
25
  </li>
26
- <template v-if="user.is_admin">
27
- <li>
28
- <a :href="`${serverDomain}/admin`"> Site Administration </a>
29
- </li>
30
- </template>
31
- <li>
26
+ <li v-if="user.is_admin" key="site-admin">
27
+ <a :href="`${serverDomain}/admin`">Site Administration</a>
28
+ </li>
29
+ <li v-if="showAccountSwitcher" :class="`is-${dropDownStatus}`" key="switcher">
30
+ <a class="
31
+ ac-dropdown-button
32
+ is-fullwidth
33
+ is-flex
34
+ is-justify-content-space-between
35
+ is-align-items-center
36
+ "
37
+ @click="toggleList()"
38
+ >
39
+ <span>Switch Account</span>
40
+ <span
41
+ ><i
42
+ :class="`fa fa-angle-${
43
+ dropDownStatus === 'open' ? 'up' : 'down'
44
+ }`"
45
+ ></i
46
+ ></span>
47
+ </a>
48
+ <transition-group name="list" tag="ul"
49
+ class="ac-vscrollbar"
50
+ ref="dropdownItems"
51
+ :style="{ maxHeight: dropDownSectionHeight }"
52
+ >
53
+ <li
54
+ v-for="(org, idx) in formattedOrganizations"
55
+ :key="org.username"
56
+ >
57
+ <a
58
+ class="is-flex is-align-items-center"
59
+ @click="onOrganizationClick(org.username)"
60
+ >
61
+ <div class="width-30 height-30 image">
62
+ <img
63
+ :src="org.avatar_url"
64
+ class="ac-user-profile is-rounded"
65
+ alt="icon"
66
+ />
67
+ </div>
68
+ <div
69
+ class="
70
+ is-flex
71
+ is-align-items-center
72
+ is-justify-content-space-between
73
+ is-fullwidth
74
+ ml-10
75
+ "
76
+ >
77
+ <div class="org-info">
78
+ <strong :title="org.username" class="is-ellipsis-1">{{ org.username }}</strong>
79
+ <p>
80
+ {{
81
+ org.isPersonalAccount
82
+ ? "Personal Account"
83
+ : "Organization"
84
+ }}
85
+ </p>
86
+ </div>
87
+ <span
88
+ v-if="idx === 0"
89
+ class="
90
+ material-icons-outlined
91
+ font-size-18
92
+ ml-10
93
+ is-pulled-right
94
+ "
95
+ >
96
+ check
97
+ </span>
98
+ </div>
99
+ </a>
100
+ </li>
101
+ </transition-group>
102
+ </li>
103
+ <li key="dashboard">
104
+ <a :href="`${serverDomain}/dashboard`"> Dashboard </a>
105
+ </li>
106
+ <li key="signout">
32
107
  <a :href="`${serverDomain}/user/logout`"> Sign out </a>
33
108
  </li>
34
- </ul>
109
+ </transition-group>
35
110
  </div>
36
111
  </navbar-item-content>
37
112
  </navbar-item>
@@ -42,6 +117,7 @@ import { defineComponent, defineAsyncComponent } from "vue";
42
117
 
43
118
  export default defineComponent({
44
119
  props: {
120
+ // active user info
45
121
  user: {
46
122
  type: Object,
47
123
  default: () => ({}),
@@ -50,6 +126,15 @@ export default defineComponent({
50
126
  type: String,
51
127
  default: "",
52
128
  },
129
+ showAccountSwitcher: {
130
+ type: Boolean,
131
+ default: false,
132
+ },
133
+ // all available organization list including personal account
134
+ organizations: {
135
+ type: Array,
136
+ default: () => [],
137
+ },
53
138
  },
54
139
 
55
140
  components: {
@@ -60,5 +145,62 @@ export default defineComponent({
60
145
  import("../../v2/navbar/NavbarItemContent.vue").then((module) => module.default)
61
146
  ),
62
147
  },
148
+
149
+ computed: {
150
+ formattedOrganizations() {
151
+ let activeUser;
152
+ const filteredList = this.organizations.filter((item) => {
153
+ if (item.username === this.user.username) {
154
+ activeUser = item;
155
+ } else {
156
+ return true;
157
+ }
158
+ return false;
159
+ });
160
+
161
+ filteredList.unshift(activeUser);
162
+
163
+ return filteredList || [];
164
+ },
165
+ },
166
+
167
+ data() {
168
+ return {
169
+ dropDownStatus: "close",
170
+ dropDownSectionHeight: null,
171
+ };
172
+ },
173
+
174
+ methods: {
175
+ toggleList() {
176
+ this.dropDownStatus = this.dropDownStatus === "open" ? "close" : "open";
177
+ },
178
+ onOrganizationClick(orgName) {
179
+ this.$refs["dropdownItems"].$el.scrollTo(0, 0);
180
+ this.$emit("activeorg$set", orgName);
181
+ },
182
+ },
183
+
184
+ watch: {
185
+ dropDownStatus: {
186
+ immediate: true,
187
+ handler(n) {
188
+ if (n === "open") {
189
+ this.$nextTick(() => {
190
+ const dropDownUl = this.$refs["dropdownItems"];
191
+ if (dropDownUl)
192
+ this.dropDownSectionHeight = `${dropDownUl.scrollHeight}px`;
193
+ });
194
+ } else {
195
+ this.dropDownSectionHeight = null;
196
+ }
197
+ },
198
+ },
199
+ },
63
200
  });
64
- </script>
201
+ </script>
202
+ <style lang="scss" scoped>
203
+ .ac-vscrollbar {
204
+ overflow: auto !important;
205
+ }
206
+ </style>
@@ -0,0 +1,133 @@
1
+ <template>
2
+ <div v-if="sidebarCollapsed" class="is-cluster-logo">
3
+ <img
4
+ width="40"
5
+ :src="getProviderIcon(selectedCluster && selectedCluster.provider)"
6
+ onerror="this.onerror=null;this.src='https://cdn.appscode.com/images/cloud-provider-icons/Generic.png';"
7
+ alt="provider-icon"
8
+ />
9
+ </div>
10
+ <multiselect
11
+ v-else
12
+ v-model="selectedCluster"
13
+ placeholder="Selected Cluster"
14
+ label="name"
15
+ track-by="name"
16
+ :options="clusterOptions"
17
+ :allow-empty="false"
18
+ deselect-label=""
19
+ select-label=""
20
+ selected-label=""
21
+ >
22
+ <template #singleLabel="props">
23
+ <div class="is-flex is-align-items-center">
24
+ <img
25
+ :src="getProviderIcon(props.option.provider)"
26
+ onerror="this.onerror=null;this.src='https://cdn.appscode.com/images/cloud-provider-icons/Generic.png';"
27
+ alt="No cluster selected"
28
+ /><span
29
+ ><span>{{ props.option.displayName }}</span></span
30
+ >
31
+ </div>
32
+ </template>
33
+ <template #option="props">
34
+ <div class="is-flex is-align-items-center">
35
+ <img
36
+ class="mr-15"
37
+ :src="getProviderIcon(props.option.provider)"
38
+ onerror="this.onerror=null;this.src='https://cdn.appscode.com/images/cloud-provider-icons/Generic.png';"
39
+ alt="No cluster selected"
40
+ />
41
+ <div>
42
+ <p>{{ props.option.displayName }}</p>
43
+ <p class="location">{{ props.option.location }}</p>
44
+ </div>
45
+ </div>
46
+ </template>
47
+ </multiselect>
48
+ </template>
49
+
50
+ <script>
51
+ import { defineComponent, defineAsyncComponent } from 'vue'
52
+ export default defineComponent({
53
+ components: {
54
+ Multiselect: defineAsyncComponent(() =>
55
+ import('vue-multiselect').then((module) => module.default)
56
+ ),
57
+ },
58
+ props: {
59
+ sidebarCollapsed: {
60
+ type: Boolean,
61
+ default: false,
62
+ },
63
+ mouseHover: {
64
+ type: Boolean,
65
+ default: false,
66
+ },
67
+ clusterOptions: {
68
+ type: Array,
69
+ default: () => [],
70
+ },
71
+ modelValue: {
72
+ type: String,
73
+ default: '',
74
+ },
75
+ },
76
+
77
+ emits: ['update:modelValue'],
78
+
79
+ data() {
80
+ return {
81
+ selectedCluster: null,
82
+ selectedClusterName: null,
83
+ }
84
+ },
85
+
86
+ watch: {
87
+ modelValue: {
88
+ immediate: true,
89
+ handler(n) {
90
+ this.selectedClusterName = n
91
+ },
92
+ },
93
+ selectedCluster: {
94
+ deep: true,
95
+ handler(n) {
96
+ if (this.selectedClusterName !== n.name) {
97
+ this.selectedClusterName = n.name
98
+ }
99
+ },
100
+ },
101
+ selectedClusterName(n) {
102
+ if (n !== this.selectedCluster.name) {
103
+ this.clusterOptions.forEach((item) => {
104
+ if (this.selectedClusterName === item.name) {
105
+ this.selectedCluster = item
106
+ }
107
+ })
108
+ }
109
+
110
+ this.$emit('update:modelValue', n)
111
+ },
112
+ clusterOptions: {
113
+ deep: true,
114
+ immediate: true,
115
+ async handler(list) {
116
+ if (list) {
117
+ list.forEach((item) => {
118
+ if (this.selectedClusterName === item.name) {
119
+ this.selectedCluster = item
120
+ }
121
+ })
122
+ }
123
+ },
124
+ },
125
+ },
126
+
127
+ methods: {
128
+ getProviderIcon(provider) {
129
+ return `https://cdn.appscode.com/images/cloud-provider-icons/${provider}.png`
130
+ },
131
+ },
132
+ })
133
+ </script>
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <li :class="`is-${dropDownStatus}`">
3
+ <a class="ac-dropdown-button" :title="title" @click="toggleDropDownStatus">
4
+ <span>
5
+ <img :src="icon" alt="icon" />
6
+ </span>
7
+ <strong>{{ title || "-" }}</strong>
8
+ <span class="ac-arrow-down">
9
+ <i class="fa fa-angle-down" aria-hidden="true"> </i>
10
+ </span>
11
+ </a>
12
+
13
+ <ul ref="sectionItems" :style="{ maxHeight: dropDownSectionHeight }">
14
+ <slot />
15
+ </ul>
16
+ </li>
17
+ </template>
18
+
19
+ <script>
20
+ import { defineComponent } from "vue";
21
+
22
+ export default defineComponent({
23
+ props: {
24
+ isDropDownOpen: {
25
+ type: Boolean,
26
+ default: false,
27
+ },
28
+ title: {
29
+ type: String,
30
+ default: "Sidebar Item",
31
+ },
32
+ icon: {
33
+ type: String,
34
+ default: "@/assets/images/icons/basic.svg",
35
+ },
36
+ },
37
+
38
+ emits: ["dropDownItemChange"],
39
+
40
+ data() {
41
+ return {
42
+ dropDownStatus: "close",
43
+ dropDownSectionHeight: null,
44
+ isCompMounted: false,
45
+ };
46
+ },
47
+
48
+ mounted() {
49
+ this.isCompMounted = true;
50
+ setTimeout(() => {
51
+ // for expanding dropdown
52
+ if (this.isDropDownOpen) {
53
+ this.setDropdownMaxHeight("open");
54
+ } else {
55
+ this.setDropdownMaxHeight("close");
56
+ }
57
+ }, 700);
58
+ },
59
+
60
+ watch: {
61
+ title(n, o) {
62
+ if (n && this.isCompMounted) {
63
+ this.$nextTick(() => {
64
+ // for expanding dropdown
65
+ this.setDropdownMaxHeight("open");
66
+ });
67
+ }
68
+
69
+ if (o && this.isCompMounted) {
70
+ this.$nextTick(() => {
71
+ // for expanding dropdown
72
+ this.setDropdownMaxHeight("close");
73
+ });
74
+ }
75
+ },
76
+ isDropDownOpen: {
77
+ immediate: true,
78
+ handler(n) {
79
+ if (n) {
80
+ this.dropDownStatus = "open";
81
+ } else this.dropDownStatus = "close";
82
+ },
83
+ },
84
+ dropDownStatus: {
85
+ immediate: true,
86
+ handler(n) {
87
+ if (n === "open") {
88
+ // emit event to close other drop down items
89
+ this.$emit("dropDownItemChange");
90
+
91
+ this.$nextTick(() => {
92
+ const dropDownUl = this.$refs["sectionItems"];
93
+ // debugger;
94
+ if (dropDownUl)
95
+ this.dropDownSectionHeight = `${dropDownUl.scrollHeight}px`;
96
+ });
97
+ } else {
98
+ // emit event to close other drop down items
99
+ this.dropDownSectionHeight = null;
100
+ }
101
+ },
102
+ },
103
+ },
104
+
105
+ methods: {
106
+ setDropdownMaxHeight(mode) {
107
+ if (mode === "open") {
108
+ this.dropDownSectionHeight = `${this.$refs["sectionItems"].scrollHeight}px`;
109
+ } else {
110
+ this.dropDownSectionHeight = null;
111
+ }
112
+ },
113
+ toggleDropDownStatus() {
114
+ if (this.dropDownStatus === "open") {
115
+ this.dropDownStatus = "close";
116
+ } else this.dropDownStatus = "open";
117
+ },
118
+ },
119
+ });
120
+ </script>
@@ -25,10 +25,32 @@
25
25
  sorting: headerSortables[idx].enabled,
26
26
  'sorting-desc': headerSortables[idx].mode === 'desc',
27
27
  'sorting-asc': headerSortables[idx].mode === 'asc',
28
+ 'has-text-centered':
29
+ typeof tableHeader === 'string'
30
+ ? false
31
+ : tableHeader.textAlign === 'center',
32
+ 'has-text-left':
33
+ typeof tableHeader === 'string'
34
+ ? false
35
+ : tableHeader.textAlign === 'left',
36
+ 'has-text-right':
37
+ typeof tableHeader === 'string'
38
+ ? false
39
+ : tableHeader.textAlign === 'right',
28
40
  }"
29
41
  @click.prevent="headerSortables[idx].enabled && emitSortEvent(idx)"
42
+ :title="tableHeader.dashboard && tableHeader.dashboard.message"
30
43
  >
31
44
  {{ headerLabels[idx] }}
45
+ <span
46
+ v-if="
47
+ tableHeader.dashboard &&
48
+ tableHeader.dashboard.status !== 'Success'
49
+ "
50
+ class="icon has-text-danger"
51
+ >
52
+ <i class="fa fa-exclamation-triangle" />
53
+ </span>
32
54
  </th>
33
55
  <th
34
56
  ref="action-section"
@@ -165,7 +187,7 @@ export default defineComponent({
165
187
  },
166
188
  headerLabels() {
167
189
  return this.tableHeaders.map((th) =>
168
- typeof th === "string" ? th : th?.label || "Label"
190
+ typeof th === "string" ? th : th?.name || "Label"
169
191
  );
170
192
  },
171
193
  },
@@ -176,8 +198,8 @@ export default defineComponent({
176
198
  handler(n) {
177
199
  if (this.headerSortables.length === n.length) {
178
200
  n.forEach((th, idx) => {
179
- if (this.headerSortables[idx].enabled !== !!th?.sortable) {
180
- this.headerSortables[idx].enabled = !!th?.sortable;
201
+ if (this.headerSortables[idx].enabled !== !!th?.sort?.enable) {
202
+ this.headerSortables[idx].enabled = !!th?.sort?.enable;
181
203
  this.headerSortables[idx].mode = "";
182
204
  }
183
205
  });
@@ -190,7 +212,7 @@ export default defineComponent({
190
212
  };
191
213
  } else {
192
214
  return {
193
- enabled: !!th?.sortable,
215
+ enabled: !!th?.sort?.enable,
194
216
  mode: "",
195
217
  };
196
218
  }
@@ -217,7 +239,7 @@ export default defineComponent({
217
239
  emitSortEvent(index) {
218
240
  const emitValue = {
219
241
  index,
220
- label: this.tableHeaders[index].label,
242
+ label: this.tableHeaders[index].name,
221
243
  mode: "",
222
244
  };
223
245
 
@@ -6,7 +6,7 @@
6
6
  custom
7
7
  v-slot="{ navigate }"
8
8
  >
9
- <tr @click="navigate" v-bind="$attrs">
9
+ <tr class="is-link" @click="navigate" v-bind="$attrs">
10
10
  <slot />
11
11
  <fake-table-cell
12
12
  v-if="fakeCellWidth > 0"
@@ -4,9 +4,11 @@
4
4
  :view-box="`0 0 ${computedCellWidth || 300} 10`"
5
5
  :speed="2"
6
6
  :key="computedCellWidth"
7
+ :primaryColor="primaryColor"
8
+ :secondaryColor="secondaryColor"
7
9
  />
8
10
  </div>
9
- <div v-else class="haha" ref="cellDiv">
11
+ <div v-else ref="cellDiv">
10
12
  <object-cell
11
13
  v-if="valueType === 'object'"
12
14
  :obj="value"
@@ -20,7 +22,7 @@
20
22
  :max-character-length="maxCharacterLength"
21
23
  />
22
24
  <template v-else>
23
- <span class="is-ellipsis-1" :title="value">{{
25
+ <span class="is-ellipsis-1" :title="tooltip">{{
24
26
  value || (value === 0 ? 0 : "-")
25
27
  }}</span>
26
28
  </template>
@@ -29,6 +31,12 @@
29
31
 
30
32
  <script>
31
33
  import { defineComponent, defineAsyncComponent } from "vue";
34
+ import {
35
+ loaderLightThemePrimaryColor,
36
+ loaderDarkThemePrimaryColor,
37
+ loaderLightThemeSecondaryColor,
38
+ loaderDarkThemeSecondaryColor,
39
+ } from "@appscode/design-system/plugins/theme";
32
40
 
33
41
  export default defineComponent({
34
42
  props: {
@@ -44,6 +52,10 @@ export default defineComponent({
44
52
  type: null,
45
53
  default: "",
46
54
  },
55
+ tooltip: {
56
+ type: String,
57
+ defualt: "",
58
+ },
47
59
  },
48
60
  components: {
49
61
  ContentLoader: defineAsyncComponent(() =>
@@ -60,13 +72,24 @@ export default defineComponent({
60
72
  computed: {
61
73
  valueType() {
62
74
  if (typeof this.value === "object") {
63
- if (Array.isArray(this.value)) return "array";
75
+ if (this.value === null) return "null";
76
+ else if (Array.isArray(this.value)) return "array";
64
77
  else return "object";
65
78
  } else return typeof this.value;
66
79
  },
67
80
  maxCharacterLength() {
68
81
  return Math.ceil(this.computedCellWidth / 8);
69
82
  },
83
+ primaryColor() {
84
+ return document.documentElement.classList.contains("is-dark-theme")
85
+ ? loaderDarkThemePrimaryColor
86
+ : loaderLightThemePrimaryColor;
87
+ },
88
+ secondaryColor() {
89
+ return document.documentElement.classList.contains("is-dark-theme")
90
+ ? loaderDarkThemeSecondaryColor
91
+ : loaderLightThemeSecondaryColor;
92
+ },
70
93
  },
71
94
 
72
95
  data() {
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <span
3
+ :class="{
4
+ 'is-flex': cellDescriptor.type !== 'object',
5
+ 'is-align-items-center': cellValue.icon,
6
+ 'is-justify-content-center': cellDescriptor.textAlign === 'center',
7
+ 'is-justify-content-left': cellDescriptor.textAlign === 'left',
8
+ 'is-justify-content-right': cellDescriptor.textAlign === 'right'
9
+ }"
10
+ >
11
+ <span v-if="cellValue.icon" class="icon p-0 mr-10">
12
+ <img width="15" :src="cellValue.icon" />
13
+ </span>
14
+ <router-link v-if="cellValue.link" :to="getCellLink(cellValue)">
15
+ {{ cellValue.data }}
16
+ </router-link>
17
+ <tag v-else-if="cellValue.color" :class="`is-${cellValue.color}`">
18
+ {{ cellValue.data }}
19
+ </tag>
20
+ <cell-value
21
+ v-else
22
+ :cell-title="cellDescriptor.name"
23
+ :value="cellValue.data || '-'"
24
+ :tooltip="cellValue.tooltip || JSON.stringify(cellValue.data)"
25
+ />
26
+ </span>
27
+ </template>
28
+
29
+ <script>
30
+ import { defineAsyncComponent, defineComponent } from "vue";
31
+ import { useRoute } from "vue-router";
32
+
33
+ export default defineComponent({
34
+ components: {
35
+ Tag: defineAsyncComponent(() => import("../../tag/Tag.vue")),
36
+ CellValue: defineAsyncComponent(() => import("../table-cell/CellValue.vue"))
37
+ },
38
+ props: {
39
+ cellDescriptor: {
40
+ type: Object,
41
+ default: () => ({})
42
+ },
43
+ cellValue: {
44
+ type: Object,
45
+ default: () => ({})
46
+ }
47
+ },
48
+ setup() {
49
+ function getCellLink(cell) {
50
+ const route = useRoute();
51
+ const inject = (str, obj) => str.replace(/\${(.*?)}/g, (x, g) => obj[g]);
52
+ const { user, cluster } = route.params;
53
+ const link = inject(cell.link || "", {
54
+ username: user,
55
+ clustername: cluster
56
+ });
57
+ return link;
58
+ }
59
+ return { getCellLink };
60
+ }
61
+ });
62
+ </script>
@@ -79,7 +79,10 @@ export default defineComponent({
79
79
  },
80
80
  printableStringObjs() {
81
81
  return this.objKeys.map((key) => {
82
- const value = this.obj[key];
82
+ let value = this.obj[key];
83
+ if (typeof value === "object" && value !== null) {
84
+ value = JSON.stringify(value);
85
+ }
83
86
  const keyValue = `${key}: ${value}`;
84
87
  const exceededLength = keyValue.length > 30;
85
88
  const print = exceededLength ? key : keyValue;
@@ -103,3 +106,4 @@ export default defineComponent({
103
106
  },
104
107
  });
105
108
  </script>
109
+
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <tabs-body class="mt-20">
2
+ <tabs-body class="mt-10">
3
3
  <tabs class="is-line">
4
4
  <tab-item :is-active="activeTab === 'edit'">
5
5
  <a @click.prevent="$emit('tabchange', 'edit')">Edit</a>