@appscode/design-system 1.0.43-alpha.99 → 1.1.0-alpha.10
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/base/utilities/_all.scss +8 -0
- package/base/utilities/_customize-bulma.scss +191 -0
- package/base/utilities/_default.scss +58 -124
- package/base/utilities/_derived-variables.scss +6 -0
- package/base/utilities/_extended.scss +38 -0
- package/base/utilities/_grid.scss +29 -0
- package/base/utilities/_initial-variables.scss +14 -10
- package/base/utilities/_typography.scss +6 -12
- package/base/utilities/dark-theme.scss +1 -0
- package/components/_ac-accordion.scss +14 -5
- package/components/_ac-alert-box.scss +32 -6
- package/components/_ac-card.scss +17 -5
- package/components/_ac-drag.scss +2 -0
- package/components/_ac-input.scss +19 -11
- package/components/_ac-modal.scss +1 -1
- package/components/_ac-multi-select.scss +60 -4
- package/components/_ac-report.scss +53 -0
- package/components/_ac-table.scss +60 -2
- package/components/_ac-tabs.scss +16 -2
- package/components/_ac-tags.scss +85 -0
- package/components/_ac-terminal.scss +1 -3
- package/components/_all.scss +29 -0
- package/components/_basic-card.scss +128 -0
- package/components/_buttons.scss +14 -33
- package/components/_dashboard-header.scss +32 -0
- package/components/_left-sidebar-menu.scss +9 -9
- package/components/_navbar.scss +89 -4
- package/components/_preview-modal.scss +14 -1
- package/components/_transitions.scss +296 -0
- package/components/_wizard.scss +1 -0
- package/components/bbum/_all.scss +9 -0
- package/components/bbum/_single-post-preview.scss +1 -1
- package/components/ui-builder/_ui-builder.scss +65 -1
- package/components/ui-builder/_vue-open-api.scss +6 -0
- package/layouts/_all.scss +2 -0
- package/layouts/_code-preview.scss +5 -2
- package/main.scss +5 -56
- package/package.json +4 -2
- package/plugins/caching.ts +243 -0
- package/plugins/time-convert.js +49 -0
- package/plugins/vue-toaster.js +3 -0
- package/vue-components/v2/banner/Banner.vue +2 -2
- package/vue-components/v2/breadcrumbs/Breadcrumb.vue +97 -0
- package/vue-components/v2/button/Button.vue +5 -0
- package/vue-components/v2/button/DownloadBtn.vue +45 -0
- package/vue-components/v2/card/Card.vue +1 -0
- package/vue-components/v2/content/ContentTable.vue +10 -0
- package/vue-components/v2/editor/Editor.vue +37 -24
- package/vue-components/v2/editor/FilteredFileEditor.vue +189 -0
- package/vue-components/v2/editor/MonacoEditor.vue +125 -0
- package/vue-components/v2/editor/ResourceKeyValueEditor.vue +209 -0
- package/vue-components/v2/form-fields/Input.vue +1 -1
- package/vue-components/v2/loaders/ResourceLoader.vue +101 -0
- package/vue-components/v2/loaders/SidebarLoader.vue +43 -0
- package/vue-components/v2/modal/Modal.vue +31 -5
- package/vue-components/v2/modals/DeleteConfirmationModal.vue +79 -0
- package/vue-components/v2/modals/JsonShowModal.vue +12 -2
- package/vue-components/v2/navbar/User.vue +229 -17
- package/vue-components/v2/notification/Notification.vue +101 -0
- package/vue-components/v2/notification/NotificationItem.vue +44 -0
- package/vue-components/v2/pagination/Pagination.vue +16 -3
- package/vue-components/v2/preloader/Preloader.vue +1 -1
- package/vue-components/v2/sidebar/SidebarItemWithDropDown.vue +19 -20
- package/vue-components/v2/tab/TabItem.vue +1 -1
- package/vue-components/v2/table/Table.vue +49 -8
- package/vue-components/v2/table/TableRow.vue +12 -2
- package/vue-components/v2/table/table-cell/CellValue.vue +29 -9
- package/vue-components/v2/table/table-cell/GenericCell.vue +56 -0
- package/vue-components/v2/table/table-cell/ObjectCell.vue +4 -1
- package/vue-components/v3/button/Button.vue +6 -1
- package/vue-components/v3/content/ContentHeader.vue +2 -1
- package/vue-components/v3/content/ContentTable.vue +25 -2
- package/vue-components/v3/editor/Editor.vue +36 -33
- package/vue-components/v3/editor/FilteredFileEditor.vue +186 -0
- package/vue-components/v3/editor/MonacoEditor.vue +131 -0
- package/vue-components/v3/editor/ResourceKeyValueEditor.vue +125 -0
- package/vue-components/v3/form/Form.vue +63 -0
- package/vue-components/v3/form-fields/Input.vue +11 -10
- package/vue-components/v3/header/HeaderItem.vue +5 -0
- package/vue-components/v3/header/HeaderItems.vue +5 -0
- package/vue-components/v3/loaders/ResourceLoader.vue +83 -0
- package/vue-components/v3/loaders/SidebarLoader.vue +34 -0
- package/vue-components/v3/long-running-tasks/LongRunningTaskItem.vue +92 -0
- package/vue-components/v3/modal/Modal.vue +35 -7
- package/vue-components/v3/modals/DeleteConfirmationModal.vue +85 -0
- package/vue-components/v3/modals/JsonShowModal.vue +25 -16
- package/vue-components/v3/modals/LongRunningTasksModal.vue +400 -0
- package/vue-components/v3/navbar/ThemeMode.vue +41 -49
- package/vue-components/v3/navbar/User.vue +242 -18
- package/vue-components/v3/notification/AlertBox.vue +61 -0
- package/vue-components/v3/notification/Notification.vue +98 -0
- package/vue-components/v3/notification/NotificationItem.vue +52 -0
- package/vue-components/v3/pagination/Pagination.vue +16 -3
- package/vue-components/v3/sidebar/SidebarItemWithDropDown.vue +120 -0
- package/vue-components/v3/tab/TabItem.vue +1 -1
- package/vue-components/v3/table/MultiInfoTable.vue +143 -0
- package/vue-components/v3/table/Table.vue +55 -14
- package/vue-components/v3/table/TableContainer.vue +34 -0
- package/vue-components/v3/table/TableRow.vue +93 -6
- package/vue-components/v3/table/table-cell/CellValue.vue +23 -7
- package/vue-components/v3/table/table-cell/GenericCell.vue +75 -0
- package/vue-components/v3/table/table-cell/ObjectCell.vue +7 -2
- package/vue-components/v3/terminal/LongRunningTaskTerminal.vue +148 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<modal
|
|
3
|
+
:open="open"
|
|
4
|
+
:title="title"
|
|
5
|
+
:is-close-option-disabled="!enableModalClose"
|
|
6
|
+
:ignore-outside-click="true"
|
|
7
|
+
:hide-action-footer="!enableModalFooter"
|
|
8
|
+
@closemodal="$emit('close')"
|
|
9
|
+
>
|
|
10
|
+
<div v-if="connectionError" class="task-simple-wrapper">
|
|
11
|
+
<div class="task-cogs-icon">
|
|
12
|
+
<i class="fa fa-times-circle has-text-danger fa-5x fa-fw"></i>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="task-log">
|
|
15
|
+
<span class="task-title">
|
|
16
|
+
<i class="fa fa-times-circle mr-5 is-failed" />
|
|
17
|
+
<span> Connection error </span>
|
|
18
|
+
</span>
|
|
19
|
+
<span>{{ connectionError }}</span>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div
|
|
23
|
+
v-else-if="isNatsConnectionLoading || !activeStepId"
|
|
24
|
+
class="is-justify-content-center"
|
|
25
|
+
:class="simple ? 'task-simple-wrapper' : 'task-complex-wrapper'"
|
|
26
|
+
>
|
|
27
|
+
<preloader
|
|
28
|
+
:style="{ height: '100%' }"
|
|
29
|
+
class="is-fullheight"
|
|
30
|
+
message="Connecting..."
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
<div v-else-if="simple" class="task-simple-wrapper">
|
|
34
|
+
<div class="task-cogs-icon">
|
|
35
|
+
<i class="fa fa-cog fa-spin fa-5x fa-fw"></i>
|
|
36
|
+
<span class="is-flex is-flex-direction-column">
|
|
37
|
+
<i class="fa fa-cog fa-spin fa-3x fa-bw"></i>
|
|
38
|
+
<i class="fa fa-cog fa-spin fa-3x fa-bw"></i>
|
|
39
|
+
</span>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="task-log">
|
|
42
|
+
<span class="task-title">
|
|
43
|
+
<i
|
|
44
|
+
v-if="activeTask?.status === 'Running'"
|
|
45
|
+
class="fa fa-circle-o-notch fa-spin mr-5"
|
|
46
|
+
/>
|
|
47
|
+
<i
|
|
48
|
+
v-else-if="activeTask?.status === 'Success'"
|
|
49
|
+
class="fa fa-check-circle mr-5 is-success"
|
|
50
|
+
/>
|
|
51
|
+
<i
|
|
52
|
+
v-else-if="activeTask?.status === 'Failed'"
|
|
53
|
+
class="fa fa-times-circle mr-5 is-failed"
|
|
54
|
+
/>
|
|
55
|
+
<span>
|
|
56
|
+
{{ activeTask?.step }}
|
|
57
|
+
</span>
|
|
58
|
+
</span>
|
|
59
|
+
<span>{{ activeTask?.logs[activeTask?.logs.length - 1] }}</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div v-else class="task-complex-wrapper">
|
|
63
|
+
<ul class="task-list">
|
|
64
|
+
<li v-for="task in tasks" :key="task.step">
|
|
65
|
+
<long-running-task-item
|
|
66
|
+
:title="task.step"
|
|
67
|
+
:status="task.status"
|
|
68
|
+
:class="{ 'is-active': activeStepId === task.id }"
|
|
69
|
+
@click="activeStepId = task.id"
|
|
70
|
+
/>
|
|
71
|
+
</li>
|
|
72
|
+
</ul>
|
|
73
|
+
<long-running-task-terminal
|
|
74
|
+
:key="activeTask?.id"
|
|
75
|
+
:theme="theme"
|
|
76
|
+
:logs="activeTask?.logs"
|
|
77
|
+
class="task-log"
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<template #modal-footer-controls>
|
|
82
|
+
<ac-button
|
|
83
|
+
title="Close"
|
|
84
|
+
modifier-classes="is-outlined"
|
|
85
|
+
@click.stop="$emit('close')"
|
|
86
|
+
/>
|
|
87
|
+
<ac-button
|
|
88
|
+
v-if="showSuccessButton"
|
|
89
|
+
:title="successCtx?.btnTitle"
|
|
90
|
+
:is-loader-active="successCtx?.isLoaderActive"
|
|
91
|
+
modifier-classes="is-primary"
|
|
92
|
+
icon-class="step-forward"
|
|
93
|
+
@click="successCtx.onSuccessBtnClick"
|
|
94
|
+
/>
|
|
95
|
+
<ac-button
|
|
96
|
+
v-if="showReportButton"
|
|
97
|
+
title="Report Issue"
|
|
98
|
+
modifier-classes="is-danger"
|
|
99
|
+
icon-class="external-link"
|
|
100
|
+
@click="onReportIssueClick"
|
|
101
|
+
/>
|
|
102
|
+
</template>
|
|
103
|
+
</modal>
|
|
104
|
+
</template>
|
|
105
|
+
<script setup lang="ts">
|
|
106
|
+
import {
|
|
107
|
+
computed,
|
|
108
|
+
getCurrentInstance,
|
|
109
|
+
onBeforeUnmount,
|
|
110
|
+
Ref,
|
|
111
|
+
toRefs,
|
|
112
|
+
watch,
|
|
113
|
+
} from "vue";
|
|
114
|
+
import { defineAsyncComponent, ref } from "vue";
|
|
115
|
+
import { Task, TaskLog } from "../../../typings/long-running-tasks.ts";
|
|
116
|
+
import { Subscription, StringCodec } from "nats.ws";
|
|
117
|
+
|
|
118
|
+
const Modal = defineAsyncComponent(() => import("../modal/Modal.vue"));
|
|
119
|
+
const LongRunningTaskItem = defineAsyncComponent(
|
|
120
|
+
() => import("../long-running-tasks/LongRunningTaskItem.vue")
|
|
121
|
+
);
|
|
122
|
+
const LongRunningTaskTerminal = defineAsyncComponent(
|
|
123
|
+
() => import("../terminal/LongRunningTaskTerminal.vue")
|
|
124
|
+
);
|
|
125
|
+
const Preloader = defineAsyncComponent(
|
|
126
|
+
() => import("../../v2/preloader/Preloader.vue")
|
|
127
|
+
);
|
|
128
|
+
const AcButton = defineAsyncComponent(() => import("../button/Button.vue"));
|
|
129
|
+
|
|
130
|
+
defineEmits(["close"]);
|
|
131
|
+
|
|
132
|
+
const props = withDefaults(
|
|
133
|
+
defineProps<{
|
|
134
|
+
open: boolean;
|
|
135
|
+
theme: string;
|
|
136
|
+
title: string;
|
|
137
|
+
simple: boolean;
|
|
138
|
+
natsSubject: string;
|
|
139
|
+
isNatsConnectionLoading: boolean;
|
|
140
|
+
errorCtx?: {
|
|
141
|
+
connectionError: string;
|
|
142
|
+
onError: (msg: string) => void;
|
|
143
|
+
};
|
|
144
|
+
successCtx?: {
|
|
145
|
+
btnTitle?: string;
|
|
146
|
+
isLoaderActive?: boolean;
|
|
147
|
+
onSuccess: () => void;
|
|
148
|
+
onSuccessBtnClick?: () => void;
|
|
149
|
+
};
|
|
150
|
+
}>(),
|
|
151
|
+
{
|
|
152
|
+
open: true,
|
|
153
|
+
theme: "light",
|
|
154
|
+
simple: true,
|
|
155
|
+
title: "Sample title",
|
|
156
|
+
natsSubject: "",
|
|
157
|
+
isNatsConnectionLoading: false,
|
|
158
|
+
errorCtx: undefined,
|
|
159
|
+
successCtx: undefined,
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const { natsSubject, open, errorCtx, successCtx } = toRefs(props);
|
|
164
|
+
const connectionError = computed(() => errorCtx.value?.connectionError);
|
|
165
|
+
const currentInstance = getCurrentInstance();
|
|
166
|
+
const $nats = currentInstance?.appContext.config.globalProperties.$nc;
|
|
167
|
+
let subscription: Subscription;
|
|
168
|
+
|
|
169
|
+
const tasks: Ref<Array<Task>> = ref([]);
|
|
170
|
+
const activeStepId: Ref<string> = ref("");
|
|
171
|
+
// to maintain stepId to stepIndex map
|
|
172
|
+
// to find active task faster
|
|
173
|
+
const idToStepIndex: Ref<Record<string, number>> = ref({});
|
|
174
|
+
const activeTask = computed(() => {
|
|
175
|
+
const task = tasks.value[idToStepIndex.value[activeStepId.value]];
|
|
176
|
+
return task;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
function handleTaskLog(log: TaskLog) {
|
|
180
|
+
if (log.step) {
|
|
181
|
+
// log has a step
|
|
182
|
+
// so add new task
|
|
183
|
+
tasks.value.push({
|
|
184
|
+
...log,
|
|
185
|
+
logs: [(log.msg && log.msg) || ""],
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// recent pushed task index
|
|
189
|
+
const latestStepIndex = tasks.value.length - 1;
|
|
190
|
+
|
|
191
|
+
// map taskid to stepIndex
|
|
192
|
+
idToStepIndex.value[log.id] = latestStepIndex;
|
|
193
|
+
|
|
194
|
+
// update active step index for first task
|
|
195
|
+
// or if current active step is in latest step
|
|
196
|
+
if (
|
|
197
|
+
latestStepIndex === 0 ||
|
|
198
|
+
latestStepIndex === idToStepIndex.value[activeStepId.value] + 1
|
|
199
|
+
) {
|
|
200
|
+
activeStepId.value = log.id;
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
// get active task
|
|
204
|
+
const task = tasks.value[idToStepIndex.value[log.id]];
|
|
205
|
+
if (task) {
|
|
206
|
+
task.status = log.status;
|
|
207
|
+
if (log.status === "Failed") {
|
|
208
|
+
task.logs.push(log.error || "");
|
|
209
|
+
errorCtx.value?.onError(log.error);
|
|
210
|
+
} else {
|
|
211
|
+
task.logs.push(log.msg || "");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function subscribeToChannel(channelId: string) {
|
|
218
|
+
subscription = $nats?.subscribe(channelId);
|
|
219
|
+
|
|
220
|
+
console.log("Started listening", channelId);
|
|
221
|
+
|
|
222
|
+
if (subscription) {
|
|
223
|
+
// listen to channel events
|
|
224
|
+
for await (const msg of subscription) {
|
|
225
|
+
console.log("Long Running Tasks Modal=>");
|
|
226
|
+
console.log({ data: StringCodec().decode(msg.data) });
|
|
227
|
+
const log: TaskLog = JSON.parse(StringCodec().decode(msg.data));
|
|
228
|
+
console.log({ log });
|
|
229
|
+
handleTaskLog(log);
|
|
230
|
+
}
|
|
231
|
+
console.log("Stopped listening", channelId);
|
|
232
|
+
console.log("Closed Channel", channelId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
watch(
|
|
237
|
+
natsSubject,
|
|
238
|
+
(n) => {
|
|
239
|
+
if (n) {
|
|
240
|
+
subscribeToChannel(n);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{ immediate: true }
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
watch(open, (n) => {
|
|
247
|
+
if (!n) {
|
|
248
|
+
subscription && subscription.unsubscribe();
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
onBeforeUnmount(() => {
|
|
252
|
+
subscription && subscription.unsubscribe();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const longRunningTaskStatus = computed(() => {
|
|
256
|
+
let successTaskCount = 0;
|
|
257
|
+
let failedTaskCount = 0;
|
|
258
|
+
|
|
259
|
+
// get count of success and failed task
|
|
260
|
+
tasks.value.forEach((task) => {
|
|
261
|
+
if (task?.status === "Success") successTaskCount++;
|
|
262
|
+
else if (task?.status === "Failed") failedTaskCount++;
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
if (tasks.value.length === 0) return "NotStarted";
|
|
266
|
+
// if all the task has been successful
|
|
267
|
+
else if (successTaskCount === tasks.value.length) {
|
|
268
|
+
return "Success";
|
|
269
|
+
}
|
|
270
|
+
// if all the task has been completed and some tasks are failed
|
|
271
|
+
else if (
|
|
272
|
+
failedTaskCount &&
|
|
273
|
+
successTaskCount + failedTaskCount === tasks.value.length
|
|
274
|
+
) {
|
|
275
|
+
return "Failed";
|
|
276
|
+
} else return "Pending";
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// modal close / footer feature
|
|
280
|
+
const enableModalClose = computed(() => {
|
|
281
|
+
return (
|
|
282
|
+
connectionError.value ||
|
|
283
|
+
longRunningTaskStatus.value === "Failed" ||
|
|
284
|
+
longRunningTaskStatus.value === "Success"
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
const enableModalFooter = computed(() => {
|
|
288
|
+
return showReportButton.value || showSuccessButton.value;
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// generate report issue title with error step title
|
|
292
|
+
const getReportIssueInfo = (): { title: string; body: string } => {
|
|
293
|
+
const stepTitlesFromErrorTasks: Array<string> = [];
|
|
294
|
+
const stepLogsFromErrorTasks: Array<string> = [];
|
|
295
|
+
tasks.value.forEach((task) => {
|
|
296
|
+
// if this taskLog is error task, push it to array
|
|
297
|
+
if (task.error) {
|
|
298
|
+
stepTitlesFromErrorTasks.push(task?.step);
|
|
299
|
+
stepLogsFromErrorTasks.push(task?.logs[task?.logs?.length - 1] || "");
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
// return final object
|
|
303
|
+
return {
|
|
304
|
+
title: stepTitlesFromErrorTasks.join(", "),
|
|
305
|
+
body: stepLogsFromErrorTasks.join(", "),
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// report button
|
|
310
|
+
const showReportButton = computed(
|
|
311
|
+
() => longRunningTaskStatus.value === "Failed"
|
|
312
|
+
);
|
|
313
|
+
function onReportIssueClick() {
|
|
314
|
+
const url = `https://github.com/bytebuilders/community/issues/new?title=Chart Install: ${
|
|
315
|
+
getReportIssueInfo().title
|
|
316
|
+
}&labels[]=bug&body=${window.location.href} %0A%0A %60%60%60 %0A ${
|
|
317
|
+
getReportIssueInfo().body
|
|
318
|
+
} %0A %60%60%60`;
|
|
319
|
+
window.open(url, "_blank");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// success button
|
|
323
|
+
const showSuccessButton = computed(
|
|
324
|
+
() =>
|
|
325
|
+
longRunningTaskStatus.value === "Success" && !!successCtx.value?.btnTitle
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
// execute on success and on error functions
|
|
329
|
+
watch(longRunningTaskStatus, (n) => {
|
|
330
|
+
if (n === "Success") {
|
|
331
|
+
successCtx.value.onSuccess();
|
|
332
|
+
} else if (n === "Failed") {
|
|
333
|
+
errorCtx.value?.onError("Operation Failed");
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
</script>
|
|
337
|
+
|
|
338
|
+
<style scoped lang="scss">
|
|
339
|
+
.task-simple-wrapper {
|
|
340
|
+
display: flex;
|
|
341
|
+
flex-direction: column;
|
|
342
|
+
justify-content: space-between;
|
|
343
|
+
width: 40vw;
|
|
344
|
+
height: 40vh;
|
|
345
|
+
.task-cogs-icon {
|
|
346
|
+
width: 100%;
|
|
347
|
+
height: 70%;
|
|
348
|
+
display: flex;
|
|
349
|
+
align-items: center;
|
|
350
|
+
justify-content: center;
|
|
351
|
+
font-size: 20px;
|
|
352
|
+
color: var(--ac-primary);
|
|
353
|
+
}
|
|
354
|
+
.task-log {
|
|
355
|
+
width: 100%;
|
|
356
|
+
height: 30%;
|
|
357
|
+
display: flex;
|
|
358
|
+
flex-direction: column;
|
|
359
|
+
align-items: center;
|
|
360
|
+
justify-content: center;
|
|
361
|
+
.task-title {
|
|
362
|
+
span,
|
|
363
|
+
i {
|
|
364
|
+
font-size: 16px;
|
|
365
|
+
}
|
|
366
|
+
i {
|
|
367
|
+
color: var(--ac-primary);
|
|
368
|
+
&.is-success {
|
|
369
|
+
color: #158748;
|
|
370
|
+
}
|
|
371
|
+
&.is-failed {
|
|
372
|
+
color: #ff3729;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
font-weight: 500;
|
|
376
|
+
}
|
|
377
|
+
span {
|
|
378
|
+
font-size: 14px;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
.task-complex-wrapper {
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-direction: row;
|
|
385
|
+
justify-content: space-between;
|
|
386
|
+
width: 60vw;
|
|
387
|
+
height: 60vh;
|
|
388
|
+
|
|
389
|
+
.task-list {
|
|
390
|
+
width: 25%;
|
|
391
|
+
height: 100%;
|
|
392
|
+
}
|
|
393
|
+
.task-log {
|
|
394
|
+
width: 70%;
|
|
395
|
+
height: 100%;
|
|
396
|
+
border-radius: 1rem;
|
|
397
|
+
font-size: 13px;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
</style>
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
</ul>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
2
|
+
<li class="mt-10 b-t-1 pt-10">
|
|
3
|
+
<ul class="ac-vscrollbar">
|
|
4
|
+
<li>
|
|
5
|
+
<div class="ac-menu-contentt theme-choicee">
|
|
6
|
+
<ul class="is-flex is-flex-direction-row is-justify-content-center">
|
|
7
|
+
<li
|
|
8
|
+
v-for="theme of Object.keys(themeModes)"
|
|
9
|
+
:title="themeModes[theme].displayName"
|
|
10
|
+
@click="themeMode = theme"
|
|
11
|
+
class="p-10 pl-30 pr-30 is-flex-grow-1 has-text-centered"
|
|
12
|
+
:class="{ 'is-active': themeMode === theme }"
|
|
13
|
+
:key="theme"
|
|
14
|
+
>
|
|
15
|
+
<i :class="['fa', themeModes[theme].iconClass]" />
|
|
16
|
+
</li>
|
|
17
|
+
</ul>
|
|
18
|
+
</div>
|
|
19
|
+
</li>
|
|
20
|
+
</ul>
|
|
21
|
+
</li>
|
|
25
22
|
</template>
|
|
26
23
|
<script>
|
|
27
24
|
import { defineComponent } from "vue";
|
|
@@ -31,10 +28,6 @@ export default defineComponent({
|
|
|
31
28
|
return {
|
|
32
29
|
themeMode: "",
|
|
33
30
|
themeModes: {
|
|
34
|
-
system: {
|
|
35
|
-
displayName: "System Theme",
|
|
36
|
-
iconClass: "fa-desktop",
|
|
37
|
-
},
|
|
38
31
|
light: {
|
|
39
32
|
displayName: "Light Theme",
|
|
40
33
|
iconClass: "fa-sun-o",
|
|
@@ -42,19 +35,23 @@ export default defineComponent({
|
|
|
42
35
|
dark: {
|
|
43
36
|
displayName: "Dark Theme",
|
|
44
37
|
iconClass: "fa-moon-o",
|
|
45
|
-
}
|
|
46
|
-
|
|
38
|
+
},
|
|
39
|
+
system: {
|
|
40
|
+
displayName: "System Theme",
|
|
41
|
+
iconClass: "fa-desktop",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
47
44
|
};
|
|
48
45
|
},
|
|
49
46
|
|
|
50
|
-
emits: [
|
|
47
|
+
emits: ["set:theme"],
|
|
51
48
|
|
|
52
49
|
mounted() {
|
|
53
50
|
// get theme mode from localStorage or set default one
|
|
54
51
|
this.themeMode = localStorage.getItem("themeMode") || "light";
|
|
55
52
|
},
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
unmounted() {
|
|
58
55
|
this.removeColorSchemeEventListener();
|
|
59
56
|
},
|
|
60
57
|
|
|
@@ -62,19 +59,16 @@ export default defineComponent({
|
|
|
62
59
|
themeMode: {
|
|
63
60
|
handler(n) {
|
|
64
61
|
this.onThemeModeChange(n);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
62
|
+
},
|
|
63
|
+
},
|
|
67
64
|
},
|
|
68
65
|
|
|
69
66
|
methods: {
|
|
70
67
|
// handle theme mode button click
|
|
71
68
|
toggleTheme() {
|
|
72
|
-
if(this.themeMode === "light")
|
|
73
|
-
|
|
74
|
-
else if(this.themeMode === "
|
|
75
|
-
this.themeMode = "system";
|
|
76
|
-
else if(this.themeMode === "system")
|
|
77
|
-
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";
|
|
78
72
|
},
|
|
79
73
|
|
|
80
74
|
// triggered when theme mode is updated
|
|
@@ -82,8 +76,10 @@ export default defineComponent({
|
|
|
82
76
|
localStorage.setItem("themeMode", n);
|
|
83
77
|
|
|
84
78
|
let theme = n;
|
|
85
|
-
if(n === "system") {
|
|
86
|
-
const isDarkMode =
|
|
79
|
+
if (n === "system") {
|
|
80
|
+
const isDarkMode =
|
|
81
|
+
window.matchMedia &&
|
|
82
|
+
window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
87
83
|
this.addColorSchemeEventListener();
|
|
88
84
|
theme = isDarkMode ? "dark" : "light";
|
|
89
85
|
} else {
|
|
@@ -95,7 +91,7 @@ export default defineComponent({
|
|
|
95
91
|
|
|
96
92
|
// add proper css class to update the ui theme
|
|
97
93
|
handleDarkThemeClass(currentTheme) {
|
|
98
|
-
if(currentTheme === "light") {
|
|
94
|
+
if (currentTheme === "light") {
|
|
99
95
|
document.documentElement.classList.remove("is-dark-theme");
|
|
100
96
|
} else {
|
|
101
97
|
document.documentElement.classList.add("is-dark-theme");
|
|
@@ -106,23 +102,19 @@ export default defineComponent({
|
|
|
106
102
|
addColorSchemeEventListener() {
|
|
107
103
|
window
|
|
108
104
|
.matchMedia("(prefers-color-scheme: dark)")
|
|
109
|
-
.addEventListener(
|
|
110
|
-
"change", this.handleSystemThemeChange
|
|
111
|
-
);
|
|
105
|
+
.addEventListener("change", this.handleSystemThemeChange);
|
|
112
106
|
},
|
|
113
107
|
|
|
114
108
|
// remove system theme listener event
|
|
115
109
|
removeColorSchemeEventListener() {
|
|
116
110
|
window
|
|
117
111
|
.matchMedia("(prefers-color-scheme: dark)")
|
|
118
|
-
.removeEventListener(
|
|
119
|
-
"change", this.handleSystemThemeChange
|
|
120
|
-
);
|
|
112
|
+
.removeEventListener("change", this.handleSystemThemeChange);
|
|
121
113
|
},
|
|
122
114
|
|
|
123
115
|
handleSystemThemeChange() {
|
|
124
116
|
this.onThemeModeChange(this.themeMode);
|
|
125
117
|
},
|
|
126
|
-
}
|
|
118
|
+
},
|
|
127
119
|
});
|
|
128
120
|
</script>
|