@appscode/design-system 1.0.43-alpha.73 → 1.0.43-alpha.77

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.
@@ -735,6 +735,147 @@ $border_color_4: transparent transparent #585d6e transparent;
735
735
  }
736
736
  }
737
737
  }
738
+ // tooltip in vue-open-api
739
+ .tooltip {
740
+ display: block !important;
741
+ z-index: 10000;
742
+
743
+ &.is-button-info {
744
+ .tooltip-inner {
745
+ background: $ac-white;
746
+ color: $ac-primary;
747
+ border-radius: 4px;
748
+ padding: 5px 20px 4px;
749
+ box-shadow: $ac-shadow-1;
750
+ font-weight: 500;
751
+ font-size: 13px;
752
+ }
753
+
754
+ .tooltip-arrow {
755
+ width: 0;
756
+ height: 0;
757
+ border-style: solid;
758
+ position: absolute;
759
+ margin: 5px;
760
+ border-color: $ac-white;
761
+ }
762
+ }
763
+
764
+ &.is-errors-tooltip {
765
+ .tooltip-inner {
766
+ background: $ac-white;
767
+ color: $ac-danger;
768
+ border-radius: 4px;
769
+ padding: 5px 20px 4px;
770
+ box-shadow: $ac-shadow-1;
771
+ font-weight: 500;
772
+ font-size: 13px;
773
+
774
+ .errors-wrapper {
775
+ .error-element {
776
+ padding: 5px 0;
777
+ }
778
+ }
779
+ }
780
+
781
+ .tooltip-arrow {
782
+ width: 0;
783
+ height: 0;
784
+ border-style: solid;
785
+ position: absolute;
786
+ margin: 5px;
787
+ border-color: $ac-white;
788
+ }
789
+ }
790
+
791
+ &[x-placement^="top"] {
792
+ margin-bottom: 5px;
793
+
794
+ .tooltip-arrow {
795
+ border-width: 5px 5px 0 5px;
796
+ border-left-color: transparent !important;
797
+ border-right-color: transparent !important;
798
+ border-bottom-color: transparent !important;
799
+ bottom: -5px;
800
+ left: calc(50% - 5px);
801
+ margin-top: 0;
802
+ margin-bottom: 0;
803
+ }
804
+ }
805
+
806
+ &[x-placement^="bottom"] {
807
+ margin-top: 5px;
808
+
809
+ .tooltip-arrow {
810
+ border-width: 0 5px 5px 5px;
811
+ border-left-color: transparent !important;
812
+ border-right-color: transparent !important;
813
+ border-top-color: transparent !important;
814
+ top: -5px;
815
+ left: calc(50% - 5px);
816
+ margin-top: 0;
817
+ margin-bottom: 0;
818
+ }
819
+ }
820
+
821
+ &[x-placement^="right"] {
822
+ margin-left: 5px;
823
+
824
+ .tooltip-arrow {
825
+ border-width: 5px 5px 5px 0;
826
+ border-left-color: transparent !important;
827
+ border-top-color: transparent !important;
828
+ border-bottom-color: transparent !important;
829
+ left: -5px;
830
+ top: calc(50% - 5px);
831
+ margin-left: 0;
832
+ margin-right: 0;
833
+ }
834
+ }
835
+
836
+ &[x-placement^="left"] {
837
+ margin-right: 5px;
838
+
839
+ .tooltip-arrow {
840
+ border-width: 5px 0 5px 5px;
841
+ border-top-color: transparent !important;
842
+ border-right-color: transparent !important;
843
+ border-bottom-color: transparent !important;
844
+ right: -5px;
845
+ top: calc(50% - 5px);
846
+ margin-left: 0;
847
+ margin-right: 0;
848
+ }
849
+ }
850
+
851
+ &.popover {
852
+ $color: #f9f9f9;
853
+
854
+ .popover-inner {
855
+ background: $color;
856
+ color: black;
857
+ padding: 24px;
858
+ border-radius: 4px;
859
+ box-shadow: $ac-shadow-1;
860
+ }
861
+
862
+ .popover-arrow {
863
+ border-color: $color;
864
+ }
865
+ }
866
+
867
+ &[aria-hidden="true"] {
868
+ visibility: hidden;
869
+ opacity: 0;
870
+ transition: opacity 0.15s, visibility 0.15s;
871
+ }
872
+
873
+ &[aria-hidden="false"] {
874
+ visibility: visible;
875
+ opacity: 1;
876
+ transition: opacity 0.15s;
877
+ }
878
+ }
738
879
 
739
880
  // Customize tooltip end
740
881
 
@@ -61,7 +61,7 @@
61
61
  position: absolute;
62
62
  content: "";
63
63
  left: 27px;
64
- top: 5px;
64
+ top: 10px;
65
65
  width: 1px;
66
66
  height: calc(100% - 20px);
67
67
  border: 1px dashed $ac-white-light;
@@ -0,0 +1,98 @@
1
+ .vue-schema-form-array {
2
+ .nested-body {
3
+ // margin-bottom: 15px;
4
+ display: flex;
5
+
6
+ .form-left-item {
7
+ margin-right: 10px;
8
+ width: calc(100% - 92px);
9
+ }
10
+ }
11
+ }
12
+
13
+ .nested-header {
14
+ .tabs.ac-tabs {
15
+ margin-bottom: 0;
16
+ opacity: 0;
17
+ visibility: hidden;
18
+ transition: 0.3s ease-in-out;
19
+ }
20
+
21
+ &:hover {
22
+ .tabs.ac-tabs {
23
+ opacity: 1;
24
+ visibility: visible;
25
+ }
26
+ }
27
+ }
28
+
29
+ .vue-openapi-form {
30
+ .ac-nested-elements {
31
+ &:first-child {
32
+ margin-left: 0;
33
+ }
34
+
35
+ .nested-body {
36
+ padding-left: 0px;
37
+ }
38
+
39
+ .nested-header {
40
+ width: 100%;
41
+ }
42
+ }
43
+
44
+ .ac-single-switch {
45
+ margin-left: -15px;
46
+ }
47
+
48
+ .ac-single-input {
49
+ margin-left: 25px;
50
+
51
+ &:last-child {
52
+ margin-bottom: 15px;
53
+ }
54
+ }
55
+ }
56
+
57
+ .vue-form-scema-body {
58
+ .left-content {
59
+ width: 650px;
60
+ background-color: $ac-white-lighter;
61
+ padding: 30px;
62
+ }
63
+
64
+ .right-content {
65
+ width: 100%;
66
+ margin-top: 30px;
67
+ }
68
+ }
69
+
70
+ .vue-openapi-form .is-warning {
71
+ font-size: 12px;
72
+ color: #ea3d2f;
73
+ font-family: Roboto, sans-serif;
74
+ padding-left: 10px;
75
+ }
76
+
77
+ .v-tooltip-open {
78
+ background-color: $ac-white;
79
+ }
80
+
81
+ .ac-nested-elements::after {
82
+ top: 25px;
83
+ width: 1px;
84
+ height: calc(100% - 50px);
85
+ }
86
+
87
+ .ac-nested-elements::before {
88
+ bottom: 12px;
89
+ }
90
+
91
+ .is-collapsed {
92
+ &.ac-nested-elements::before,
93
+ &.ac-nested-elements::after {
94
+ display: none;
95
+ }
96
+ }
97
+
98
+ // for vue-tooltip
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appscode/design-system",
3
- "version": "1.0.43-alpha.73",
3
+ "version": "1.0.43-alpha.77",
4
4
  "description": "A design system for Appscode websites and dashboards made using Bulma",
5
5
  "main": "main.scss",
6
6
  "scripts": {
@@ -19,6 +19,7 @@
19
19
  },
20
20
  theme: theme,
21
21
  readOnly: readOnly,
22
+ wordWrap: wordWrap,
22
23
  scrollBeyondLastLine: false
23
24
  }"
24
25
  />
@@ -34,6 +35,7 @@
34
35
  },
35
36
  theme: theme,
36
37
  readOnly: true,
38
+ wordWrap: wordWrap,
37
39
  scrollBeyondLastLine: false
38
40
  }"
39
41
  :original="originalEditorContent"
@@ -72,7 +74,11 @@ export default {
72
74
  editorTheme: {
73
75
  type: String,
74
76
  default: ""
75
- }
77
+ },
78
+ wordWrap: {
79
+ type: String,
80
+ default: "off"
81
+ },
76
82
  },
77
83
  components: {
78
84
  EditorTabs: () => import("../tabs/EditorTabs.vue"),
@@ -17,6 +17,7 @@
17
17
  <header-item>
18
18
  <ac-button
19
19
  modifier-classes="is-square is-transparent"
20
+ :disabled="isCloseOptionDisabled"
20
21
  :icon-image="require('@/assets/images/icons/close-icon.svg')"
21
22
  @click.stop="destroyModal"
22
23
  />
@@ -36,7 +37,10 @@
36
37
  <!-- modal body end -->
37
38
 
38
39
  <!-- modal footer start -->
39
- <div class="ac-modal-footer action-footer">
40
+ <div class="ac-modal-footer action-footer is-flex is-align-items-center is-justify-content-space-between">
41
+ <div>
42
+ <slot name="modal-footer-left" />
43
+ </div>
40
44
  <buttons class="has-text-right is-block">
41
45
  <slot name="modal-footer-controls" />
42
46
  </buttons>
@@ -62,6 +66,10 @@ export default {
62
66
  type: String,
63
67
  default: "",
64
68
  },
69
+ isCloseOptionDisabled: {
70
+ type: Boolean,
71
+ default: false,
72
+ }
65
73
  },
66
74
 
67
75
  components: {
@@ -102,6 +110,7 @@ export default {
102
110
  document.addEventListener("keydown", this.onKeyDown);
103
111
  },
104
112
  destroyModal() {
113
+ if (this.isCloseOptionDisabled) return;
105
114
  this.showModal = false;
106
115
  document.removeEventListener("keydown", this.onKeyDown);
107
116
 
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <div class="is-cluster-logo" v-if="sidebarCollapsed">
3
+ <img
4
+ width="40"
5
+ :src="getProviderIcon(selectedCluster && selectedCluster.provider)"
6
+ alt=""
7
+ />
8
+ </div>
9
+ <multiselect
10
+ v-else
11
+ v-model="selectedCluster"
12
+ placeholder="Selected Cluster"
13
+ label="name"
14
+ track-by="uid"
15
+ :options="options"
16
+ :allow-empty="false"
17
+ deselectLabel=""
18
+ selectLabel=""
19
+ selectedLabel=""
20
+ >
21
+ <template slot="singleLabel" slot-scope="props">
22
+ <div class="is-flex is-align-items-center">
23
+ <img
24
+ :src="getProviderIcon(props.option.provider)"
25
+ alt="No cluster selected"
26
+ /><span
27
+ ><span>{{ props.option.displayName }}</span></span
28
+ >
29
+ </div>
30
+ </template>
31
+ <template slot="option" slot-scope="props">
32
+ <div class="is-flex is-align-items-center">
33
+ <img
34
+ class="mr-15"
35
+ :src="getProviderIcon(props.option.provider)"
36
+ alt="No cluster selected"
37
+ />
38
+ <div>
39
+ <p>{{ props.option.displayName }}</p>
40
+ <p class="location">{{ props.option.location }}</p>
41
+ </div>
42
+ </div>
43
+ </template>
44
+ </multiselect>
45
+ </template>
46
+
47
+ <script>
48
+ import { mapGetters } from "vuex";
49
+ export default {
50
+ props: {
51
+ sidebarCollapsed: {
52
+ type: Boolean,
53
+ default: false,
54
+ },
55
+ mouseHover: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+ username: {
60
+ type: String,
61
+ default: "",
62
+ },
63
+ imagePath: {
64
+ type: Object,
65
+ default: () => ({}),
66
+ },
67
+ value: {
68
+ type: Object,
69
+ default: () => ({}),
70
+ },
71
+ },
72
+
73
+ components: {
74
+ Multiselect: () => import("vue-multiselect"),
75
+ },
76
+
77
+ data() {
78
+ return {
79
+ selectedCluster: null,
80
+ clusters: [],
81
+ options: [],
82
+ };
83
+ },
84
+
85
+ computed: {
86
+ selectClusterOptions() {
87
+ return this.clusters
88
+ .filter(
89
+ (cluster) =>
90
+ cluster.status.phase === "Connected" ||
91
+ cluster.status.phase === "PrivateConnected"
92
+ )
93
+ .map((cluster) => {
94
+ return {
95
+ name: cluster.spec.name,
96
+ displayName: cluster.spec.displayName,
97
+ provider: cluster.spec.provider,
98
+ uid: cluster.spec.uid,
99
+ location: cluster.spec.location,
100
+ };
101
+ });
102
+ },
103
+ },
104
+
105
+ methods: {
106
+ async checkStatus(clusterName) {
107
+ try {
108
+ await this.$axios.get(
109
+ `/clusters/${this.username}/${clusterName}/status`
110
+ );
111
+ return true;
112
+ } catch (err) {
113
+ return false;
114
+ }
115
+ },
116
+ async getClusters() {
117
+ if (this.username) {
118
+ const url = `/clusters/${this.username}`;
119
+
120
+ try {
121
+ const resp = await this.$axios.get(url);
122
+ this.clusters = (resp.data && resp.data.items) || [];
123
+
124
+ // preselect the cluster
125
+ const selectedCluster = this.clusters.find(
126
+ (cluster) => cluster.spec.name === this.$route.params.cluster
127
+ );
128
+ this.selectedCluster = {
129
+ name: selectedCluster.spec.name,
130
+ displayName: selectedCluster.spec.displayName,
131
+ provider: selectedCluster.spec.provider,
132
+ uid: selectedCluster.spec.uid,
133
+ location: selectedCluster.spec.location,
134
+ };
135
+ } catch (e) {
136
+ console.log(e);
137
+ }
138
+ }
139
+ },
140
+
141
+ getProviderIcon(provider) {
142
+ return this.imagePath[provider] || this.imagePath["default"];
143
+ },
144
+ },
145
+
146
+ created() {
147
+ this.getClusters();
148
+ },
149
+
150
+ watch: {
151
+ value: {
152
+ deep: true,
153
+ immediate: true,
154
+ handler(n) {
155
+ this.selectedCluster = n;
156
+ },
157
+ },
158
+ selectClusterOptions: {
159
+ deep: true,
160
+ immediate: true,
161
+ async handler(list) {
162
+ this.options = [];
163
+ if (list) {
164
+ list.forEach(async (item) => {
165
+ const resp = await this.checkStatus(item.name);
166
+ if (resp) this.options.push(item);
167
+ });
168
+ }
169
+ },
170
+ },
171
+ },
172
+ };
173
+ </script>
@@ -20,6 +20,7 @@
20
20
  },
21
21
  theme: theme,
22
22
  readOnly: readOnly,
23
+ wordWrap: wordWrap,
23
24
  scrollBeyondLastLine: false
24
25
  }"
25
26
  />
@@ -35,6 +36,7 @@
35
36
  },
36
37
  theme: theme,
37
38
  readOnly: true,
39
+ wordWrap: wordWrap,
38
40
  scrollBeyondLastLine: false
39
41
  }"
40
42
  :original="originalEditorContent"
@@ -74,7 +76,11 @@ export default defineComponent({
74
76
  editorTheme: {
75
77
  type: String,
76
78
  default: ""
77
- }
79
+ },
80
+ wordWrap: {
81
+ type: String,
82
+ default: "off"
83
+ },
78
84
  },
79
85
 
80
86
  emits: ["update:modelValue"],
@@ -17,6 +17,7 @@
17
17
  <header-item>
18
18
  <ac-button
19
19
  modifier-classes="is-square is-transparent"
20
+ :disabled="isCloseOptionDisabled"
20
21
  :icon-image="crossIcon"
21
22
  @click.stop="destroyModal"
22
23
  />
@@ -36,7 +37,10 @@
36
37
  <!-- modal body end -->
37
38
 
38
39
  <!-- modal footer start -->
39
- <div class="ac-modal-footer action-footer">
40
+ <div class="ac-modal-footer action-footer is-flex is-align-items-center is-justify-content-space-between">
41
+ <div>
42
+ <slot name="modal-footer-left" />
43
+ </div>
40
44
  <buttons class="has-text-right is-block">
41
45
  <slot name="modal-footer-controls" />
42
46
  </buttons>
@@ -64,6 +68,10 @@ export default defineComponent({
64
68
  type: String,
65
69
  default: "",
66
70
  },
71
+ isCloseOptionDisabled: {
72
+ type: Boolean,
73
+ default: false,
74
+ }
67
75
  },
68
76
  emits: ["closemodal"],
69
77
 
@@ -116,6 +124,7 @@ export default defineComponent({
116
124
  document.addEventListener("keydown", this.onKeyDown);
117
125
  },
118
126
  destroyModal() {
127
+ if (this.isCloseOptionDisabled) return;
119
128
  this.showModal = false;
120
129
  document.removeEventListener("keydown", this.onKeyDown);
121
130
 
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <div class="is-cluster-logo" v-if="sidebarCollapsed">
3
+ <img
4
+ width="40"
5
+ :src="getProviderIcon(selectedCluster && selectedCluster.provider)"
6
+ alt=""
7
+ />
8
+ </div>
9
+ <multiselect
10
+ v-else
11
+ v-model="selectedCluster"
12
+ placeholder="Selected Cluster"
13
+ label="name"
14
+ track-by="uid"
15
+ :options="options"
16
+ :allow-empty="false"
17
+ deselectLabel=""
18
+ selectLabel=""
19
+ selectedLabel=""
20
+ >
21
+ <template slot="singleLabel" slot-scope="props">
22
+ <div class="is-flex is-align-items-center">
23
+ <img
24
+ :src="getProviderIcon(props.option.provider)"
25
+ alt="No cluster selected"
26
+ /><span
27
+ ><span>{{ props.option.displayName }}</span></span
28
+ >
29
+ </div>
30
+ </template>
31
+ <template slot="option" slot-scope="props">
32
+ <div class="is-flex is-align-items-center">
33
+ <img
34
+ class="mr-15"
35
+ :src="getProviderIcon(props.option.provider)"
36
+ alt="No cluster selected"
37
+ />
38
+ <div>
39
+ <p>{{ props.option.displayName }}</p>
40
+ <p class="location">{{ props.option.location }}</p>
41
+ </div>
42
+ </div>
43
+ </template>
44
+ </multiselect>
45
+ </template>
46
+
47
+ <script>
48
+ import { defineComponent, defineAsyncComponent } from "vue";
49
+ export default defineComponent({
50
+ props: {
51
+ sidebarCollapsed: {
52
+ type: Boolean,
53
+ default: false,
54
+ },
55
+ mouseHover: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+ username: {
60
+ type: String,
61
+ default: "",
62
+ },
63
+ imagePath: {
64
+ type: Object,
65
+ default: () => ({}),
66
+ },
67
+ value: {
68
+ type: Object,
69
+ default: () => ({}),
70
+ },
71
+ },
72
+
73
+ components: {
74
+ Multiselect: () => import("vue-multiselect"),
75
+ },
76
+
77
+ data() {
78
+ return {
79
+ selectedCluster: null,
80
+ clusters: [],
81
+ options: [],
82
+ };
83
+ },
84
+
85
+ computed: {
86
+ selectClusterOptions() {
87
+ return this.clusters
88
+ .filter(
89
+ (cluster) =>
90
+ cluster.status.phase === "Connected" ||
91
+ cluster.status.phase === "PrivateConnected"
92
+ )
93
+ .map((cluster) => {
94
+ return {
95
+ name: cluster.spec.name,
96
+ displayName: cluster.spec.displayName,
97
+ provider: cluster.spec.provider,
98
+ uid: cluster.spec.uid,
99
+ location: cluster.spec.location,
100
+ };
101
+ });
102
+ },
103
+ },
104
+
105
+ methods: {
106
+ async checkStatus(clusterName) {
107
+ try {
108
+ await this.$axios.get(
109
+ `/clusters/${this.username}/${clusterName}/status`
110
+ );
111
+ return true;
112
+ } catch (err) {
113
+ return false;
114
+ }
115
+ },
116
+ async getClusters() {
117
+ if (this.username) {
118
+ const url = `/clusters/${this.username}`;
119
+
120
+ try {
121
+ const resp = await this.$axios.get(url);
122
+ this.clusters = (resp.data && resp.data.items) || [];
123
+
124
+ // preselect the cluster
125
+ const selectedCluster = this.clusters.find(
126
+ (cluster) => cluster.spec.name === this.$route.params.cluster
127
+ );
128
+ this.selectedCluster = {
129
+ name: selectedCluster.spec.name,
130
+ displayName: selectedCluster.spec.displayName,
131
+ provider: selectedCluster.spec.provider,
132
+ uid: selectedCluster.spec.uid,
133
+ location: selectedCluster.spec.location,
134
+ };
135
+ } catch (e) {
136
+ console.log(e);
137
+ }
138
+ }
139
+ },
140
+
141
+ getProviderIcon(provider) {
142
+ return this.imagePath[provider] || this.imagePath["default"];
143
+ },
144
+ },
145
+
146
+ created() {
147
+ this.getClusters();
148
+ },
149
+
150
+ watch: {
151
+ value: {
152
+ deep: true,
153
+ immediate: true,
154
+ handler(n) {
155
+ this.selectedCluster = n;
156
+ },
157
+ },
158
+ selectClusterOptions: {
159
+ deep: true,
160
+ immediate: true,
161
+ async handler(list) {
162
+ this.options = [];
163
+ if (list) {
164
+ list.forEach(async (item) => {
165
+ const resp = await this.checkStatus(item.name);
166
+ if (resp) this.options.push(item);
167
+ });
168
+ }
169
+ },
170
+ },
171
+ },
172
+ });
173
+ </script>