@nethserver/ns8-ui-lib 0.0.43 → 0.0.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nethserver/ns8-ui-lib",
3
- "version": "0.0.43",
3
+ "version": "0.0.47",
4
4
  "description": "Vue.js library for NethServer 8 UI",
5
5
  "keywords": [
6
6
  "nethserver",
@@ -27,105 +27,83 @@
27
27
  </div>
28
28
  </template>
29
29
  <template v-else>
30
- <div v-for="backup in backupsContainingInstance" :key="backup.id">
31
- <div class="row">
32
- <h5
33
- v-if="backupsContainingInstance.length > 1"
34
- class="title mg-top-sm"
35
- >
36
- {{ backup.name }}
37
- </h5>
38
- </div>
39
- <div class="table-wrapper">
40
- <div class="table">
41
- <!-- status -->
42
- <div class="tr">
43
- <div class="td label">{{ statusLabel }}</div>
44
- <div class="td status">
45
- <span v-if="!backup.enabled" class="ns-warning">
46
- {{ backupDisabledLabel }}
47
- </span>
48
- <span
49
- v-else-if="
50
- status[backup.id] && status[backup.id].success == true
51
- "
52
- class="ns-success"
53
- >
54
- <span>{{ statusSuccessLabel }}</span>
55
- </span>
56
- <span
57
- v-else-if="
58
- status[backup.id] && status[backup.id].success == false
59
- "
60
- class="ns-error"
61
- >
62
- {{ statusErrorLabel }}
63
- </span>
64
- <span v-else class="ns-warning">
65
- {{ statusNotRunLabel }}
66
- </span>
67
- </div>
68
- </div>
69
- <!-- repository -->
70
- <div class="tr">
71
- <div class="td label">{{ repositoryLabel }}</div>
72
- <div class="td">
73
- {{ backup.repoName }}
74
- </div>
75
- </div>
76
- <!-- completed -->
77
- <div class="tr">
78
- <div class="td label">{{ completedLabel }}</div>
79
- <div class="td">
80
- <span v-if="status[backup.id] && status[backup.id].end">
81
- {{
82
- (status[backup.id].end * 1000) | date("yyyy-MM-dd HH:mm:ss")
83
- }}
84
- </span>
85
- <span v-else>-</span>
86
- </div>
87
- </div>
88
- <!-- duration -->
89
- <div class="tr">
90
- <div class="td label">{{ durationLabel }}</div>
91
- <div class="td">
92
- <span
93
- v-if="
94
- status[backup.id] &&
95
- status[backup.id].end &&
96
- status[backup.id].start
97
- "
98
- >
99
- {{
100
- (status[backup.id].end - status[backup.id].start)
101
- | secondsFormat
102
- }}
103
- </span>
104
- <span v-else>-</span>
105
- </div>
106
- </div>
107
- <!-- total size -->
108
- <div class="tr">
109
- <div class="td label">{{ totalSizeLabel }}</div>
110
- <div class="td">
111
- <span v-if="status[backup.id] && status[backup.id].total_size">
112
- {{ status[backup.id].total_size | byteFormat }}
113
- </span>
114
- <span v-else>-</span>
30
+ <div class="backups">
31
+ <div
32
+ v-for="backup in backupsContainingInstance"
33
+ :key="backup.id"
34
+ class="backup"
35
+ >
36
+ <div class="row">
37
+ <h5
38
+ v-if="backupsContainingInstance.length > 1"
39
+ class="title mg-top-sm"
40
+ >
41
+ {{ backup.name }}
42
+ </h5>
43
+ </div>
44
+ <div class="table-wrapper">
45
+ <div class="table">
46
+ <!-- status -->
47
+ <div class="tr">
48
+ <div class="td label">{{ statusLabel }}</div>
49
+ <div class="td status">
50
+ <span v-if="!backup.enabled" class="ns-warning">
51
+ {{ backupDisabledLabel }}
52
+ </span>
53
+ <span
54
+ v-else-if="
55
+ status[backup.id] && status[backup.id].success == true
56
+ "
57
+ class="ns-success"
58
+ >
59
+ <span>{{ statusSuccessLabel }}</span>
60
+ </span>
61
+ <span
62
+ v-else-if="
63
+ status[backup.id] && status[backup.id].success == false
64
+ "
65
+ class="ns-error"
66
+ >
67
+ {{ statusErrorLabel }}
68
+ </span>
69
+ <span v-else class="ns-warning">
70
+ {{ statusNotRunLabel }}
71
+ </span>
72
+ </div>
115
73
  </div>
74
+ <NsBackupCardDetails
75
+ v-if="backupsContainingInstance.length == 1"
76
+ :backup="backup"
77
+ :status="status"
78
+ :repositoryLabel="repositoryLabel"
79
+ :completedLabel="completedLabel"
80
+ :durationLabel="durationLabel"
81
+ :totalSizeLabel="totalSizeLabel"
82
+ :totalFileCountLabel="totalFileCountLabel"
83
+ />
116
84
  </div>
117
- <!-- total file count -->
118
- <div class="tr">
119
- <div class="td label">{{ totalFileCountLabel }}</div>
120
- <div class="td">
121
- <span
122
- v-if="status[backup.id] && status[backup.id].total_file_count"
123
- >
124
- {{ status[backup.id].total_file_count | humanFormat }}
125
- ({{ status[backup.id].total_file_count }})
126
- </span>
127
- <span v-else>-</span>
128
- </div>
85
+ </div>
86
+ <div class="table-wrapper">
87
+ <div class="table">
88
+ <cv-accordion
89
+ v-if="backupsContainingInstance.length > 1"
90
+ ref="accordion"
91
+ >
92
+ <cv-accordion-item :open="toggleAccordion[0]">
93
+ <template slot="title">{{ showMoreLabel }}</template>
94
+ <template slot="content">
95
+ <NsBackupCardDetails
96
+ :backup="backup"
97
+ :status="status"
98
+ :repositoryLabel="repositoryLabel"
99
+ :completedLabel="completedLabel"
100
+ :durationLabel="durationLabel"
101
+ :totalSizeLabel="totalSizeLabel"
102
+ :totalFileCountLabel="totalFileCountLabel"
103
+ />
104
+ </template>
105
+ </cv-accordion-item>
106
+ </cv-accordion>
129
107
  </div>
130
108
  </div>
131
109
  </div>
@@ -147,10 +125,13 @@
147
125
 
148
126
  <script>
149
127
  import IconService from "../lib-mixins/icon.js";
150
-
128
+ import UtilService from "../lib-mixins/util.js";
129
+ // import DateTimeService from "../lib-mixins/dateTime.js"; ////
130
+ import NsBackupCardDetails from "./NsBackupCardDetails";
151
131
  export default {
152
132
  name: "NsBackupCard",
153
- mixins: [IconService],
133
+ components: { NsBackupCardDetails },
134
+ mixins: [IconService, UtilService],
154
135
  props: {
155
136
  title: {
156
137
  type: String,
@@ -208,6 +189,10 @@ export default {
208
189
  type: String,
209
190
  default: "Disabled",
210
191
  },
192
+ showMoreLabel: {
193
+ type: String,
194
+ default: "Show more",
195
+ },
211
196
  moduleId: {
212
197
  type: String,
213
198
  required: true,
@@ -274,7 +259,7 @@ export default {
274
259
  }
275
260
  },
276
261
  goToBackup() {
277
- if (this.coreContext) {
262
+ if (this.coreContext && this.coreContext.$router) {
278
263
  this.coreContext.$router.push("/backup");
279
264
  }
280
265
  },
@@ -290,6 +275,14 @@ export default {
290
275
  min-height: 7rem;
291
276
  }
292
277
 
278
+ .backup {
279
+ margin-bottom: 1rem;
280
+ }
281
+
282
+ .backup:last-child {
283
+ margin-bottom: 0;
284
+ }
285
+
293
286
  .row {
294
287
  display: flex;
295
288
  align-items: center;
@@ -338,3 +331,11 @@ export default {
338
331
  margin-right: 0.25rem;
339
332
  }
340
333
  </style>
334
+
335
+ <style lang="scss">
336
+ // global styles
337
+
338
+ .ns-backup-card .bx--accordion--start .bx--accordion__content {
339
+ margin-left: 0;
340
+ }
341
+ </style>
@@ -0,0 +1,136 @@
1
+ <template>
2
+ <div class="ns-backup-card-details">
3
+ <!-- repository -->
4
+ <div class="tr">
5
+ <div class="td label">{{ repositoryLabel }}</div>
6
+ <div class="td">
7
+ {{ backup.repoName }}
8
+ </div>
9
+ </div>
10
+ <!-- completed -->
11
+ <div class="tr">
12
+ <div class="td label">{{ completedLabel }}</div>
13
+ <div class="td">
14
+ <span v-if="status[backup.id] && status[backup.id].end">
15
+ <cv-interactive-tooltip
16
+ alignment="center"
17
+ direction="bottom"
18
+ class="info tooltip-with-text-trigger"
19
+ >
20
+ <template slot="trigger">
21
+ {{
22
+ formatDateDistance(status[backup.id].end * 1000, new Date(), {
23
+ addSuffix: true,
24
+ })
25
+ }}
26
+ </template>
27
+ <template slot="content">
28
+ {{ (status[backup.id].end * 1000) | date("yyyy-MM-dd HH:mm:ss") }}
29
+ </template>
30
+ </cv-interactive-tooltip>
31
+ </span>
32
+ <span v-else>-</span>
33
+ </div>
34
+ </div>
35
+ <!-- duration -->
36
+ <div class="tr">
37
+ <div class="td label">{{ durationLabel }}</div>
38
+ <div class="td">
39
+ <span
40
+ v-if="
41
+ status[backup.id] &&
42
+ status[backup.id].end &&
43
+ status[backup.id].start
44
+ "
45
+ >
46
+ {{
47
+ (status[backup.id].end - status[backup.id].start) | secondsFormat
48
+ }}
49
+ </span>
50
+ <span v-else>-</span>
51
+ </div>
52
+ </div>
53
+ <!-- total size -->
54
+ <div class="tr">
55
+ <div class="td label">{{ totalSizeLabel }}</div>
56
+ <div class="td">
57
+ <span v-if="status[backup.id] && status[backup.id].total_size">
58
+ {{ status[backup.id].total_size | byteFormat }}
59
+ </span>
60
+ <span v-else>-</span>
61
+ </div>
62
+ </div>
63
+ <!-- total file count -->
64
+ <div class="tr">
65
+ <div class="td label">{{ totalFileCountLabel }}</div>
66
+ <div class="td">
67
+ <span v-if="status[backup.id] && status[backup.id].total_file_count">
68
+ {{ status[backup.id].total_file_count | humanFormat }}
69
+ ({{ status[backup.id].total_file_count }})
70
+ </span>
71
+ <span v-else>-</span>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </template>
76
+
77
+ <script>
78
+ import DateTimeService from "../lib-mixins/dateTime.js";
79
+
80
+ export default {
81
+ name: "NsBackupCardDetails",
82
+ mixins: [DateTimeService],
83
+ props: {
84
+ backup: {
85
+ type: Object,
86
+ required: true,
87
+ },
88
+ status: {
89
+ type: Array,
90
+ required: true,
91
+ },
92
+ repositoryLabel: {
93
+ type: String,
94
+ default: "Repository",
95
+ },
96
+ completedLabel: {
97
+ type: String,
98
+ required: true,
99
+ },
100
+ durationLabel: {
101
+ type: String,
102
+ required: true,
103
+ },
104
+ totalSizeLabel: {
105
+ type: String,
106
+ required: true,
107
+ },
108
+ totalFileCountLabel: {
109
+ type: String,
110
+ required: true,
111
+ },
112
+ },
113
+ };
114
+ </script>
115
+
116
+ <style scoped lang="scss">
117
+ .ns-backup-card-details {
118
+ // do not render root div, only table rows
119
+ display: contents;
120
+ }
121
+
122
+ .tr {
123
+ display: table-row;
124
+ }
125
+
126
+ .td {
127
+ display: table-cell;
128
+ }
129
+
130
+ .label {
131
+ padding-right: 0.75rem;
132
+ font-weight: bold;
133
+ text-align: right;
134
+ padding-bottom: 0.5rem;
135
+ }
136
+ </style>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <cv-side-nav-divider />
3
+ </template>
4
+
5
+ <script>
6
+ import CvSideNavDivider from "@carbon/vue/src/components/cv-ui-shell/cv-side-nav-divider.vue";
7
+
8
+ export default {
9
+ name: "NsMenuDivider",
10
+ components: { CvSideNavDivider },
11
+ };
12
+ </script>
13
+
14
+ <style scoped lang="scss"></style>
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <div class="ns-menu-item">
3
+ <span v-if="icon == 'edit'" class="icon"><Edit20 /></span>
4
+ <span v-else-if="icon == 'trash'" class="icon"><TrashCan20 /></span>
5
+ <span v-else-if="icon == 'power'" class="icon"><Power20 /></span>
6
+ <span v-else-if="icon == 'rocket'" class="icon"><Rocket20 /></span>
7
+ <span v-else-if="icon == 'launch'" class="icon"><Launch20 /></span>
8
+ <span v-else-if="icon == 'star'" class="icon"><Star20 /></span>
9
+ <span v-else-if="hasIconSlot" class="icon">
10
+ <slot name="icon"></slot>
11
+ </span>
12
+ <span>{{ label }}</span>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ import Edit20 from "@carbon/icons-vue/es/edit/20";
18
+ import TrashCan20 from "@carbon/icons-vue/es/trash-can/20";
19
+ import Power20 from "@carbon/icons-vue/es/power/20";
20
+ import Rocket20 from "@carbon/icons-vue/es/rocket/20";
21
+ import Launch20 from "@carbon/icons-vue/es/launch/20";
22
+ import Star20 from "@carbon/icons-vue/es/star/20";
23
+
24
+ export default {
25
+ name: "NsMenuItem",
26
+ components: { Edit20, TrashCan20, Power20, Rocket20, Launch20, Star20 },
27
+ props: {
28
+ label: {
29
+ type: String,
30
+ required: true,
31
+ },
32
+ icon: {
33
+ type: String,
34
+ validator: (value) =>
35
+ ["", "edit", "trash", "power", "rocket", "launch", "star"].includes(
36
+ value
37
+ ),
38
+ },
39
+ },
40
+ computed: {
41
+ hasIconSlot() {
42
+ return !!this.$slots.icon;
43
+ },
44
+ },
45
+ };
46
+ </script>
47
+
48
+ <style scoped lang="scss">
49
+ .ns-menu-item {
50
+ display: flex;
51
+ align-items: center;
52
+ }
53
+
54
+ .icon {
55
+ margin-right: 0.5rem;
56
+ }
57
+ </style>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <div
3
+ data-modal
4
+ :id="uid"
5
+ :class="[
6
+ `cv-modal ${carbonPrefix}--modal`,
7
+ `wizard-modal`,
8
+ {
9
+ 'is-visible': dataVisible,
10
+ },
11
+ ]"
12
+ tabindex="-1"
13
+ @keydown.esc.prevent="onEsc"
14
+ @click.self="onExternalClick"
15
+ >
16
+ <div
17
+ :class="[
18
+ `${carbonPrefix}--modal-container`,
19
+ { [`${carbonPrefix}--modal-container--${internalSize}`]: internalSize },
20
+ ]"
21
+ v-bind="dialogAttrs"
22
+ ref="modalDialog"
23
+ >
24
+ <div
25
+ class="cv-modal__before-content"
26
+ ref="beforeContent"
27
+ tabindex="0"
28
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
29
+ @focus="focusBeforeContent"
30
+ />
31
+ <div :class="`${carbonPrefix}--modal-header`">
32
+ <p :class="`${carbonPrefix}--modal-header__label`">
33
+ <slot name="label"></slot>
34
+ </p>
35
+ <p :class="`${carbonPrefix}--modal-header__heading`">
36
+ <slot name="title">Modal Title</slot>
37
+ </p>
38
+ <button
39
+ :class="`${carbonPrefix}--modal-close`"
40
+ type="button"
41
+ @click="onClose"
42
+ ref="close"
43
+ :aria-label="closeAriaLabel"
44
+ >
45
+ <Close16 :class="`${carbonPrefix}--modal-close__icon`" />
46
+ </button>
47
+ </div>
48
+ <div
49
+ :class="[
50
+ `${carbonPrefix}--modal-content`,
51
+ { [`${carbonPrefix}--modal-content--with-form`]: hasFormContent },
52
+ ]"
53
+ ref="content"
54
+ :tabindex="scrollable ? 0 : undefined"
55
+ >
56
+ <slot name="content"></slot>
57
+ </div>
58
+
59
+ <cv-button-set
60
+ :class="[
61
+ `${carbonPrefix}--modal-footer`,
62
+ `${carbonPrefix}--modal-footer--three-button`,
63
+ ]"
64
+ >
65
+ <NsButton
66
+ kind="secondary"
67
+ :icon="Close20"
68
+ @click="$emit('cancel')"
69
+ type="button"
70
+ class="wizard-button"
71
+ >{{ cancelLabel }}
72
+ </NsButton>
73
+ <NsButton
74
+ kind="secondary"
75
+ :icon="ChevronLeft20"
76
+ @click="$emit('previousStep')"
77
+ :disabled="isPreviousDisabled"
78
+ type="button"
79
+ class="wizard-button"
80
+ >{{ previousLabel }}
81
+ </NsButton>
82
+ <NsButton
83
+ kind="primary"
84
+ :icon="ChevronRight20"
85
+ @click="$emit('nextStep')"
86
+ :disabled="isNextDisabled"
87
+ :loading="isNextLoading"
88
+ type="submit"
89
+ class="wizard-button"
90
+ ref="wizardNext"
91
+ >{{ nextLabel }}
92
+ </NsButton>
93
+ </cv-button-set>
94
+ <div
95
+ class="cv-modal__after-content"
96
+ ref="afterContent"
97
+ tabindex="0"
98
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
99
+ @focus="focusAfterContent"
100
+ />
101
+ </div>
102
+ </div>
103
+ </template>
104
+
105
+ <script>
106
+ import { CvModal } from "@carbon/vue";
107
+ import IconService from "../lib-mixins/icon.js";
108
+
109
+ export default {
110
+ name: "NsWizard",
111
+ extends: CvModal,
112
+ mixins: [IconService],
113
+ props: {
114
+ cancelLabel: { type: String, default: "Cancel" },
115
+ previousLabel: { type: String, default: "Previous" },
116
+ nextLabel: { type: String, default: "Next" },
117
+ isPreviousDisabled: Boolean,
118
+ isNextDisabled: Boolean,
119
+ isNextLoading: Boolean,
120
+ closeAriaLabel: { type: String, default: "Close modal" },
121
+ autoHideOff: Boolean,
122
+ visible: Boolean,
123
+ size: String,
124
+ },
125
+ };
126
+ </script>