@appscode/design-system 1.0.43-alpha.21 → 1.0.43-alpha.211

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 (132) hide show
  1. package/base/utilities/_all.scss +7 -0
  2. package/base/utilities/_customize-bulma.scss +191 -0
  3. package/base/utilities/_default.scss +313 -67
  4. package/base/utilities/_derived-variables.scss +6 -1
  5. package/base/utilities/_grid.scss +29 -0
  6. package/base/utilities/_initial-variables.scss +27 -17
  7. package/base/utilities/_mixin.scss +1 -17
  8. package/base/utilities/_typography.scss +18 -14
  9. package/base/utilities/dark-theme.scss +9 -145
  10. package/components/_ac-accordion.scss +14 -5
  11. package/components/_ac-alert-box.scss +41 -7
  12. package/components/_ac-card.scss +48 -10
  13. package/components/_ac-code-highlight.scss +5 -1
  14. package/components/_ac-content-layout.scss +2 -2
  15. package/components/_ac-drag.scss +2 -0
  16. package/components/_ac-input.scss +64 -23
  17. package/components/_ac-modal.scss +1 -1
  18. package/components/_ac-multi-select.scss +247 -9
  19. package/components/_ac-options.scss +24 -9
  20. package/components/_ac-select-box.scss +13 -3
  21. package/components/_ac-table.scss +7 -5
  22. package/components/_ac-tabs.scss +46 -5
  23. package/components/_ac-terminal.scss +270 -0
  24. package/components/_all.scss +27 -0
  25. package/components/_app-drawer.scss +2 -2
  26. package/components/_breadcumb.scss +2 -0
  27. package/components/_buttons.scss +50 -37
  28. package/components/_card-body-wrapper.scss +2 -2
  29. package/components/_dashboard-header.scss +32 -0
  30. package/components/_direct-deploy.scss +69 -0
  31. package/components/_go-to-top.scss +1 -1
  32. package/components/_graph.scss +45 -0
  33. package/components/_image-upload.scss +5 -3
  34. package/components/_left-sidebar-menu.scss +124 -73
  35. package/components/_monaco-editor.scss +1 -1
  36. package/components/_navbar.scss +170 -10
  37. package/components/_overview-info.scss +3 -3
  38. package/components/_pagination.scss +8 -0
  39. package/components/_payment-card.scss +10 -1
  40. package/components/_preview-modal.scss +18 -5
  41. package/components/_pricing-table.scss +1 -1
  42. package/components/_progress-bar.scss +4 -4
  43. package/components/_subscription-card.scss +11 -4
  44. package/components/_table-of-content.scss +1 -1
  45. package/components/_tfa.scss +69 -0
  46. package/components/_transitions.scss +261 -0
  47. package/components/_wizard.scss +16 -3
  48. package/components/bbum/_all.scss +9 -0
  49. package/components/bbum/_card-team.scss +1 -1
  50. package/components/bbum/_information-center.scss +15 -1
  51. package/components/bbum/_sign-up-notification.scss +1 -1
  52. package/components/bbum/_single-post-preview.scss +2 -2
  53. package/components/bbum/_user-profile.scss +2 -3
  54. package/components/ui-builder/_ui-builder.scss +76 -1
  55. package/components/ui-builder/_vue-open-api.scss +104 -0
  56. package/layouts/_all.scss +2 -0
  57. package/layouts/_code-preview.scss +5 -2
  58. package/main.scss +6 -54
  59. package/package.json +2 -7
  60. package/plugins/theme.js +4 -0
  61. package/plugins/time-convert.js +49 -0
  62. package/plugins/vue-toaster.js +3 -0
  63. package/vue-components/v2/banner/Banner.vue +2 -2
  64. package/vue-components/v2/breadcrumbs/Breadcrumb.vue +97 -0
  65. package/vue-components/v2/button/Button.vue +5 -0
  66. package/vue-components/v2/button/DownloadBtn.vue +45 -0
  67. package/vue-components/v2/card/Card.vue +1 -0
  68. package/vue-components/v2/card/PaymentCards.vue +11 -2
  69. package/vue-components/v2/content/ContentTable.vue +12 -7
  70. package/vue-components/v2/editor/Editor.vue +43 -24
  71. package/vue-components/v2/editor/FilteredFileEditor.vue +189 -0
  72. package/vue-components/v2/editor/MonacoEditor.vue +125 -0
  73. package/vue-components/v2/editor/ResourceKeyValueEditor.vue +209 -0
  74. package/vue-components/v2/form-fields/Input.vue +1 -1
  75. package/vue-components/v2/loaders/ResourceLoader.vue +101 -0
  76. package/vue-components/v2/loaders/SidebarLoader.vue +43 -0
  77. package/vue-components/v2/modal/Modal.vue +38 -4
  78. package/vue-components/v2/modals/DeleteConfirmationModal.vue +79 -0
  79. package/vue-components/v2/modals/JsonShowModal.vue +12 -2
  80. package/vue-components/v2/navbar/Appdrawer.vue +10 -9
  81. package/vue-components/v2/navbar/ThemeMode.vue +50 -44
  82. package/vue-components/v2/navbar/User.vue +229 -17
  83. package/vue-components/v2/notification/Notification.vue +101 -0
  84. package/vue-components/v2/notification/NotificationItem.vue +44 -0
  85. package/vue-components/v2/pagination/Pagination.vue +16 -3
  86. package/vue-components/v2/preloader/Preloader.vue +5 -5
  87. package/vue-components/v2/sidebar/ClusterSwitcher.vue +126 -0
  88. package/vue-components/v2/sidebar/SidebarItem.vue +23 -1
  89. package/vue-components/v2/sidebar/SidebarItemWithDropDown.vue +19 -20
  90. package/vue-components/v2/tab/TabItem.vue +1 -1
  91. package/vue-components/v2/table/Table.vue +44 -8
  92. package/vue-components/v2/table/TableRow.vue +12 -2
  93. package/vue-components/v2/table/table-cell/CellValue.vue +33 -4
  94. package/vue-components/v2/table/table-cell/GenericCell.vue +56 -0
  95. package/vue-components/v2/table/table-cell/ObjectCell.vue +4 -1
  96. package/vue-components/v2/tabs/EditorTabs.vue +1 -1
  97. package/vue-components/v3/button/Button.vue +6 -1
  98. package/vue-components/v3/content/ContentTable.vue +17 -2
  99. package/vue-components/v3/editor/Editor.vue +42 -33
  100. package/vue-components/v3/editor/FilteredFileEditor.vue +186 -0
  101. package/vue-components/v3/editor/MonacoEditor.vue +131 -0
  102. package/vue-components/v3/editor/ResourceKeyValueEditor.vue +125 -0
  103. package/vue-components/v3/form/Form.vue +63 -0
  104. package/vue-components/v3/form-fields/Input.vue +11 -10
  105. package/vue-components/v3/header/HeaderItem.vue +5 -0
  106. package/vue-components/v3/header/HeaderItems.vue +5 -0
  107. package/vue-components/v3/loaders/ResourceLoader.vue +83 -0
  108. package/vue-components/v3/loaders/SidebarLoader.vue +34 -0
  109. package/vue-components/v3/long-running-tasks/LongRunningTaskItem.vue +92 -0
  110. package/vue-components/v3/modal/Modal.vue +38 -6
  111. package/vue-components/v3/modals/DeleteConfirmationModal.vue +85 -0
  112. package/vue-components/v3/modals/JsonShowModal.vue +25 -16
  113. package/vue-components/v3/modals/LongRunningTasksModal.vue +337 -0
  114. package/vue-components/v3/navbar/Appdrawer.vue +12 -7
  115. package/vue-components/v3/navbar/ThemeMode.vue +49 -47
  116. package/vue-components/v3/navbar/User.vue +242 -18
  117. package/vue-components/v3/notification/Notification.vue +98 -0
  118. package/vue-components/v3/notification/NotificationItem.vue +52 -0
  119. package/vue-components/v3/pagination/Pagination.vue +16 -3
  120. package/vue-components/v3/sidebar/ClusterSwitcher.vue +133 -0
  121. package/vue-components/v3/sidebar/SidebarItemWithDropDown.vue +120 -0
  122. package/vue-components/v3/tab/TabItem.vue +1 -1
  123. package/vue-components/v3/table/MultiInfoTable.vue +143 -0
  124. package/vue-components/v3/table/Table.vue +40 -12
  125. package/vue-components/v3/table/TableContainer.vue +34 -0
  126. package/vue-components/v3/table/TableRow.vue +62 -3
  127. package/vue-components/v3/table/table-cell/CellValue.vue +28 -3
  128. package/vue-components/v3/table/table-cell/GenericCell.vue +75 -0
  129. package/vue-components/v3/table/table-cell/ObjectCell.vue +5 -1
  130. package/vue-components/v3/tabs/EditorTabs.vue +1 -1
  131. package/vue-components/v3/tag/Tag.vue +1 -1
  132. package/vue-components/v3/terminal/LongRunningTaskTerminal.vue +148 -0
@@ -6,7 +6,7 @@
6
6
  v-if="showModal"
7
7
  class="ac-modal is-middle-alignment"
8
8
  :class="modifierClasses"
9
- @click.self="destroyModal"
9
+ @click.self="onModalOutsideClick"
10
10
  >
11
11
  <div class="ac-modal-inner">
12
12
  <!-- modal header start -->
@@ -17,7 +17,11 @@
17
17
  <header-item>
18
18
  <ac-button
19
19
  modifier-classes="is-square is-transparent"
20
- :icon-image="require('@/assets/images/icons/close-icon.svg')"
20
+ :disabled="isCloseOptionDisabled"
21
+ :icon-image="
22
+ require('@appscode/design-system-images/icons/close-icon.svg')
23
+ "
24
+ data-testid="delete-confirmation-modal-close-icon"
21
25
  @click.stop="destroyModal"
22
26
  />
23
27
  </header-item>
@@ -26,7 +30,10 @@
26
30
  <!-- modal header end -->
27
31
 
28
32
  <!-- modal body start -->
29
- <div class="ac-modal-body">
33
+ <div
34
+ class="ac-modal-body ac-vscrollbar"
35
+ data-testid="ac-modal-content-with-scroll"
36
+ >
30
37
  <div class="ac-modal-content">
31
38
  <!-- freedom content start -->
32
39
  <slot />
@@ -36,7 +43,17 @@
36
43
  <!-- modal body end -->
37
44
 
38
45
  <!-- modal footer start -->
39
- <div class="ac-modal-footer action-footer">
46
+ <div
47
+ v-if="!hideActionFooter"
48
+ class="
49
+ ac-modal-footer
50
+ action-footer
51
+ is-flex is-align-items-center is-justify-content-space-between
52
+ "
53
+ >
54
+ <div>
55
+ <slot name="modal-footer-left" />
56
+ </div>
40
57
  <buttons class="has-text-right is-block">
41
58
  <slot name="modal-footer-controls" />
42
59
  </buttons>
@@ -62,6 +79,18 @@ export default {
62
79
  type: String,
63
80
  default: "",
64
81
  },
82
+ isCloseOptionDisabled: {
83
+ type: Boolean,
84
+ default: false,
85
+ },
86
+ ignoreOutsideClick: {
87
+ type: Boolean,
88
+ default: false,
89
+ },
90
+ hideActionFooter: {
91
+ type: Boolean,
92
+ default: false,
93
+ },
65
94
  },
66
95
 
67
96
  components: {
@@ -97,11 +126,16 @@ export default {
97
126
  this.destroyModal();
98
127
  }
99
128
  },
129
+ onModalOutsideClick() {
130
+ if (this.ignoreOutsideClick) return;
131
+ this.destroyModal();
132
+ },
100
133
  initializeModal() {
101
134
  this.showModal = true;
102
135
  document.addEventListener("keydown", this.onKeyDown);
103
136
  },
104
137
  destroyModal() {
138
+ if (this.isCloseOptionDisabled) return;
105
139
  this.showModal = false;
106
140
  document.removeEventListener("keydown", this.onKeyDown);
107
141
 
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <!-- modal start -->
3
+ <modal
4
+ :title="title"
5
+ modifier-classes="is-normal"
6
+ :open="open"
7
+ @closemodal="closeModal"
8
+ >
9
+ <!-- freedom content start -->
10
+ <div class="action-message pt-35 pb-35 has-text-centered">
11
+ <h5 class="is-message">{{ message }} {{ itemName ? "" : "?" }}</h5>
12
+ <p class="is-description">{{ itemName }} {{ itemName ? "?" : "" }}</p>
13
+ </div>
14
+
15
+ <!-- freedom content end -->
16
+
17
+ <!-- modal footer start -->
18
+ <template #modal-footer-controls>
19
+ <ac-button
20
+ @click.stop="closeModal"
21
+ title="Cancel"
22
+ modifier-classes="is-outlined"
23
+ data-testid="delete-confirmation-modal-close-button"
24
+ />
25
+ <ac-button
26
+ modifier-classes="is-danger"
27
+ :is-loader-active="isDeleteActive"
28
+ title="Yes"
29
+ data-testid="delete-confirmation-modal-confirm-button"
30
+ @click.stop="confirm(true)"
31
+ />
32
+ </template>
33
+ </modal>
34
+ <!-- modal end -->
35
+ </template>
36
+
37
+ <script>
38
+ export default {
39
+ components: {
40
+ Modal: () => import("./../modal/Modal.vue"),
41
+ AcButton: () => import("./../button/Button.vue"),
42
+ },
43
+ props: {
44
+ open: {
45
+ type: Boolean,
46
+ default: false,
47
+ },
48
+ title: {
49
+ type: String,
50
+ default: "",
51
+ },
52
+ message: {
53
+ type: String,
54
+ default: "",
55
+ },
56
+ itemName: {
57
+ type: String,
58
+ default: "",
59
+ },
60
+ isLoading: {
61
+ type: Boolean,
62
+ default: false,
63
+ },
64
+ isDeleteActive: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ },
69
+ methods: {
70
+ confirm(response) {
71
+ this.$emit("delete-confirmation-modal$confirm", response);
72
+ },
73
+ closeModal() {
74
+ this.confirm(false);
75
+ this.$emit("closemodal", true);
76
+ },
77
+ },
78
+ };
79
+ </script>
@@ -10,7 +10,9 @@
10
10
  <ac-button
11
11
  modifier-classes="is-square is-primary"
12
12
  icon-class="copy"
13
- v-clipboard:copy="`${editorTitle}: &quot;${editorContent}&quot;`"
13
+ v-clipboard:copy="
14
+ `${editorTitle}: ${JSON.stringify(parsedContent, null, 4)}`
15
+ "
14
16
  v-clipboard:success="onCopy"
15
17
  v-clipboard:error="onError"
16
18
  />
@@ -26,6 +28,8 @@
26
28
  </template>
27
29
 
28
30
  <script>
31
+ import Preloader from "../preloader/Preloader.vue";
32
+ import Banner from "../banner/Banner.vue";
29
33
  export default {
30
34
  props: {
31
35
  open: {
@@ -43,7 +47,13 @@ export default {
43
47
  },
44
48
  components: {
45
49
  Modal: () => import("../modal/Modal.vue"),
46
- Editor: () => import("../editor/Editor.vue"),
50
+ Editor: () => ({
51
+ component: import("../editor/Editor.vue"),
52
+ loading: Preloader,
53
+ delay: 200,
54
+ error: Banner,
55
+ timeout: 100000,
56
+ }),
47
57
  AcButton: () => import("../button/Button.vue"),
48
58
  HeaderItem: () => import("../header/HeaderItem.vue"),
49
59
  },
@@ -1,10 +1,13 @@
1
1
  <template>
2
- <div class="app-drawer-wrapper d-table-cell">
3
- <div class="drawer-icon">
2
+ <div class="app-drawer-wrapper is-flex">
3
+ <div
4
+ class="drawer-icon is-flex is-justify-content-center is-align-items-center"
5
+ >
4
6
  <svg
5
7
  class="gb_We"
6
8
  focusable="false"
7
9
  viewBox="0 0 24 24"
10
+ style="width: 22px;margin-top: 2px;"
8
11
  :style="{ fill: 'white' }"
9
12
  >
10
13
  <path
@@ -20,16 +23,14 @@
20
23
  <article class="media">
21
24
  <figure class="media-left">
22
25
  <p class="image">
23
- <img
24
- :src="app.icon_url"
25
- />
26
+ <img :src="app.icon_url" />
26
27
  </p>
27
28
  </figure>
28
29
  <div class="media-content">
29
30
  <div class="content">
30
31
  <p>
31
- <strong>{{app.title}}</strong>
32
- <span>{{app.sub_title}}</span>
32
+ <strong>{{ app.title }}</strong>
33
+ <span>{{ app.sub_title }}</span>
33
34
  </p>
34
35
  </div>
35
36
  </div>
@@ -50,7 +51,7 @@ export default {
50
51
  }
51
52
  },
52
53
  components: {
53
- NavbarItemContent: () => import("./NavbarItemContent.vue"),
54
- },
54
+ NavbarItemContent: () => import("./NavbarItemContent.vue")
55
+ }
55
56
  };
56
57
  </script>
@@ -1,38 +1,49 @@
1
1
  <template>
2
- <button v-if="themeMode" class="button ac-nav-button" @click="toggleTheme" :title="themeModeIconTooltip" >
3
- <i :class="`fa ${themeModeIconClass} width-15`" />
4
- </button>
2
+ <div>
3
+ <button
4
+ v-if="themeMode"
5
+ class="button ac-nav-button"
6
+ style="color: #ffffff; font-size: 15px;"
7
+ @click="toggleTheme"
8
+ :title="themeModes[themeMode].displayName"
9
+ >
10
+ <i :class="`fa ${themeModes[themeMode].iconClass}`" />
11
+ </button>
12
+ <div class="ac-menu-content theme-choice">
13
+ <ul class="is-flex is-flex-direction-row is-justify-content-space-around">
14
+ <li
15
+ v-for="theme of Object.keys(themeModes)"
16
+ :title="themeModes[theme].displayName"
17
+ @click="themeMode = theme"
18
+ :class="{'is-active': themeMode === theme}"
19
+ :key="theme"
20
+ >
21
+ <i :class="['fa', themeModes[theme].iconClass]" />
22
+ </li>
23
+ </ul>
24
+ </div>
25
+ </div>
5
26
  </template>
6
27
  <script>
7
28
  export default {
8
29
  data() {
9
30
  return {
10
31
  themeMode: "",
11
- };
12
- },
13
-
14
- computed: {
15
- // to set icon class for theme mode
16
- themeModeIconClass() {
17
- if(this.themeMode === "system") {
18
- return "fa-desktop";
19
- } else if(this.themeMode === "light") {
20
- return "fa-sun-o";
21
- } else if(this.themeMode === "dark") {
22
- return "fa-moon-o";
23
- }
24
- },
25
-
26
- // to set icon tooltip for theme mode
27
- themeModeIconTooltip() {
28
- if(this.themeMode === "system") {
29
- return "System theme";
30
- } else if(this.themeMode === "light") {
31
- return "Light theme";
32
- } else if(this.themeMode === "dark") {
33
- return "Dark theme";
32
+ themeModes: {
33
+ system: {
34
+ displayName: "System Theme",
35
+ iconClass: "fa-desktop",
36
+ },
37
+ light: {
38
+ displayName: "Light Theme",
39
+ iconClass: "fa-sun-o",
40
+ },
41
+ dark: {
42
+ displayName: "Dark Theme",
43
+ iconClass: "fa-moon-o",
44
+ }
34
45
  }
35
- }
46
+ };
36
47
  },
37
48
 
38
49
  mounted() {
@@ -55,12 +66,9 @@ export default {
55
66
  methods: {
56
67
  // handle theme mode button click
57
68
  toggleTheme() {
58
- if(this.themeMode === "light")
59
- this.themeMode = "dark";
60
- else if(this.themeMode === "dark")
61
- this.themeMode = "system";
62
- else if(this.themeMode === "system")
63
- this.themeMode = "light";
69
+ if (this.themeMode === "light") this.themeMode = "dark";
70
+ else if (this.themeMode === "dark") this.themeMode = "system";
71
+ else if (this.themeMode === "system") this.themeMode = "light";
64
72
  },
65
73
 
66
74
  // triggered when theme mode is updated
@@ -68,8 +76,10 @@ export default {
68
76
  localStorage.setItem("themeMode", n);
69
77
 
70
78
  let theme = n;
71
- if(n === "system") {
72
- const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
79
+ if (n === "system") {
80
+ const isDarkMode =
81
+ window.matchMedia &&
82
+ window.matchMedia("(prefers-color-scheme: dark)").matches;
73
83
  this.addColorSchemeEventListener();
74
84
  theme = isDarkMode ? "dark" : "light";
75
85
  } else {
@@ -81,7 +91,7 @@ export default {
81
91
 
82
92
  // add proper css class to update the ui theme
83
93
  handleDarkThemeClass(currentTheme) {
84
- if(currentTheme === "light") {
94
+ if (currentTheme === "light") {
85
95
  document.documentElement.classList.remove("is-dark-theme");
86
96
  } else {
87
97
  document.documentElement.classList.add("is-dark-theme");
@@ -92,23 +102,19 @@ export default {
92
102
  addColorSchemeEventListener() {
93
103
  window
94
104
  .matchMedia("(prefers-color-scheme: dark)")
95
- .addEventListener(
96
- "change", this.handleSystemThemeChange
97
- );
105
+ .addEventListener("change", this.handleSystemThemeChange);
98
106
  },
99
107
 
100
108
  // remove system theme listener event
101
109
  removeColorSchemeEventListener() {
102
110
  window
103
111
  .matchMedia("(prefers-color-scheme: dark)")
104
- .removeEventListener(
105
- "change", this.handleSystemThemeChange
106
- );
112
+ .removeEventListener("change", this.handleSystemThemeChange);
107
113
  },
108
114
 
109
115
  handleSystemThemeChange() {
110
116
  this.onThemeModeChange(this.themeMode);
111
- },
117
+ }
112
118
  }
113
- }
119
+ };
114
120
  </script>
@@ -7,31 +7,155 @@
7
7
  <img :src="user.avatar_url" alt="User Photo" />
8
8
  </div>
9
9
  </button>
10
- <navbar-item-content>
11
- <div v-if="user.username" class="user-profile-wrapper">
10
+ <navbar-item-content class="navbar-dropdown-wrapper">
11
+ <div
12
+ v-if="user.username"
13
+ class="user-profile-wrapper"
14
+ @mouseleave="onMouseLeave()"
15
+ >
12
16
  <div class="profile-area">
13
17
  <div class="profile-photo">
14
- <img :src="user.avatar_url" alt="User Photo" />
18
+ <img
19
+ :src="user.avatar_url"
20
+ alt="User Photo"
21
+ class="width-50 height-50"
22
+ />
15
23
  <button class="camera-icon"></button>
16
24
  </div>
17
- <div class="profile-info">
18
- <p>{{ user.username.toUpperCase() }}</p>
25
+ <div class="profile-info" style="width: calc(100% - 60px)">
26
+ <a
27
+ :href="`${serverDomain}/${user.username}`"
28
+ :title="user.username.toUpperCase()"
29
+ data-testid="user-profile-link"
30
+ class="line-break-anywhere is-ellipsis-1"
31
+ >{{ user.username.toUpperCase() }}</a
32
+ >
19
33
  <a :href="`mailto:${user.email}`"> {{ user.email }}</a>
20
34
  </div>
21
35
  </div>
22
- <ul>
23
- <li>
24
- <a :href="`${serverDomain}/user/settings/`">Settings</a>
36
+ <transition-group name="list" tag="ul">
37
+ <li key="settings">
38
+ <a
39
+ data-testid="user-settings-link"
40
+ :href="`${serverDomain}/user/settings/`"
41
+ >Settings</a
42
+ >
25
43
  </li>
26
- <template v-if="user.is_admin">
27
- <li>
28
- <a :href="`${serverDomain}/admin`"> Site Administration </a>
29
- </li>
30
- </template>
31
- <li>
32
- <a :href="`${serverDomain}/user/logout`"> Sign out </a>
44
+ <li v-if="isLoggedinUserAdmin" key="site-admin">
45
+ <a data-testid="site-admin-link" :href="`${accountsDomain}/admin`"
46
+ >Site Administration</a
47
+ >
33
48
  </li>
34
- </ul>
49
+ <li
50
+ v-if="showAccountSwitcher"
51
+ :class="`is-${dropDownStatus}`"
52
+ key="switcher"
53
+ >
54
+ <a
55
+ class="
56
+ ac-dropdown-button
57
+ is-fullwidth
58
+ is-flex
59
+ is-justify-content-space-between
60
+ is-align-items-center
61
+ "
62
+ @click="toggleList()"
63
+ >
64
+ <span>Switch Account</span>
65
+ <span
66
+ ><i
67
+ :class="`fa fa-angle-${
68
+ dropDownStatus === 'open' ? 'up' : 'down'
69
+ }`"
70
+ ></i
71
+ ></span>
72
+ </a>
73
+ <transition-group
74
+ name="list"
75
+ tag="ul"
76
+ class="ac-vscrollbar"
77
+ ref="dropdownItems"
78
+ :style="{ maxHeight: dropDownSectionHeight }"
79
+ >
80
+ <li
81
+ v-for="(org, idx) in formattedOrganizations"
82
+ :key="org.username"
83
+ >
84
+ <a
85
+ class="is-flex is-align-items-center"
86
+ @click="onOrganizationClick(org.username)"
87
+ >
88
+ <div class="width-30 height-30 image">
89
+ <img
90
+ :src="org.avatar_url"
91
+ class="ac-user-profile is-rounded"
92
+ alt="icon"
93
+ />
94
+ </div>
95
+ <div
96
+ class="
97
+ is-flex
98
+ is-align-items-center
99
+ is-justify-content-space-between
100
+ is-fullwidth
101
+ ml-10
102
+ "
103
+ >
104
+ <div class="org-info">
105
+ <strong
106
+ :title="org.username"
107
+ class="line-break-anywhere is-ellipsis-1"
108
+ >{{ org.username }}</strong
109
+ >
110
+ <p>
111
+ {{
112
+ org.isPersonalAccount
113
+ ? "Personal Account"
114
+ : "Organization"
115
+ }}
116
+ </p>
117
+ </div>
118
+ <span
119
+ v-if="idx === 0"
120
+ class="
121
+ material-icons-outlined
122
+ font-size-18
123
+ ml-10
124
+ is-pulled-right
125
+ "
126
+ >
127
+ check
128
+ </span>
129
+ </div>
130
+ </a>
131
+ </li>
132
+ </transition-group>
133
+ </li>
134
+ <li key="dashboard">
135
+ <nuxt-link
136
+ v-if="isPlatformDomain"
137
+ to="/dashboard"
138
+ data-testid="user-dashboard-link"
139
+ >
140
+ Dashboard
141
+ </nuxt-link>
142
+ <a
143
+ v-else
144
+ :href="`${serverDomain}/dashboard`"
145
+ data-testid="user-dashboard-link"
146
+ >
147
+ Dashboard
148
+ </a>
149
+ </li>
150
+ <li key="signout">
151
+ <a
152
+ :href="`${accountsDomain}/user/logout`"
153
+ data-testid="signout-link"
154
+ >
155
+ Sign out
156
+ </a>
157
+ </li>
158
+ </transition-group>
35
159
  </div>
36
160
  </navbar-item-content>
37
161
  </navbar-item>
@@ -40,6 +164,7 @@
40
164
  <script>
41
165
  export default {
42
166
  props: {
167
+ // active user info
43
168
  user: {
44
169
  type: Object,
45
170
  default: () => ({}),
@@ -48,11 +173,98 @@ export default {
48
173
  type: String,
49
174
  default: "",
50
175
  },
176
+ accountsDomain: {
177
+ type: String,
178
+ default: "",
179
+ },
180
+ showAccountSwitcher: {
181
+ type: Boolean,
182
+ default: false,
183
+ },
184
+ // all available organization list including personal account
185
+ organizations: {
186
+ type: Array,
187
+ default: () => [],
188
+ },
189
+ isLoggedinUserAdmin: {
190
+ type: Boolean,
191
+ default: false,
192
+ },
193
+ isPlatformDomain: {
194
+ type: Boolean,
195
+ default: false,
196
+ },
51
197
  },
52
198
 
53
199
  components: {
54
200
  NavbarItem: () => import("./NavbarItem.vue"),
55
201
  NavbarItemContent: () => import("./NavbarItemContent.vue"),
56
202
  },
203
+
204
+ computed: {
205
+ formattedOrganizations() {
206
+ let activeUser;
207
+ const filteredList = this.organizations.filter((item) => {
208
+ if (item.username === this.user.username) {
209
+ activeUser = item;
210
+ } else {
211
+ return true;
212
+ }
213
+ return false;
214
+ });
215
+
216
+ filteredList.unshift(activeUser);
217
+
218
+ return filteredList || [];
219
+ },
220
+ },
221
+
222
+ data() {
223
+ return {
224
+ dropDownStatus: "close",
225
+ dropDownSectionHeight: null,
226
+ };
227
+ },
228
+
229
+ methods: {
230
+ toggleList() {
231
+ this.dropDownStatus = this.dropDownStatus === "open" ? "close" : "open";
232
+ this.$nextTick(() => {
233
+ this.$refs["dropdownItems"].$el.scrollTo(0, 0);
234
+ });
235
+ },
236
+ onOrganizationClick(orgName) {
237
+ this.$refs["dropdownItems"].$el.scrollTo(0, 0);
238
+ this.$emit("activeorg$set", orgName);
239
+ },
240
+ onMouseLeave() {
241
+ this.dropDownStatus = "close";
242
+ },
243
+ },
244
+
245
+ watch: {
246
+ dropDownStatus: {
247
+ immediate: true,
248
+ handler(n) {
249
+ if (n === "open") {
250
+ this.$nextTick(() => {
251
+ const dropDownUl = this.$refs["dropdownItems"];
252
+ if (dropDownUl)
253
+ this.dropDownSectionHeight = `${dropDownUl.scrollHeight}px`;
254
+ });
255
+ } else {
256
+ this.dropDownSectionHeight = null;
257
+ }
258
+ },
259
+ },
260
+ },
57
261
  };
58
- </script>
262
+ </script>
263
+ <style lang="scss" scoped>
264
+ .ac-vscrollbar {
265
+ overflow: auto !important;
266
+ }
267
+ .line-break-anywhere {
268
+ line-break: anywhere;
269
+ }
270
+ </style>