jobdone-shared-files 1.0.24 → 1.0.31
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/ProjectManagement/projectNavbar.vue +363 -363
- package/ProjectManagement/projectNavbarV2.vue +362 -0
- package/README.md +9 -8
- package/autocompleteSelect.vue +465 -461
- package/common/directives/collapse.js +12 -12
- package/common/directives/popovers.js +10 -10
- package/common/directives/selectPlaceholder.js +52 -52
- package/common/directives/textareaAutoHeight.js +10 -10
- package/common/directives/tooltip.js +10 -10
- package/common/format.js +26 -26
- package/index.js +14 -14
- package/lightboxWithOverview.vue +156 -156
- package/package.json +19 -19
- package/paginate.vue +141 -141
- package/style/css/vue-loading-overlay/index.css +40 -40
- package/style/scss/Common/Animation.scss +9 -9
- package/style/scss/Common/SelectableTable.scss +36 -36
- package/style/scss/Common/filepond.scss +31 -31
- package/style/scss/Common/thumbnail-group.scss +14 -14
- package/style/scss/Layout/LayoutBase.scss +1032 -1032
- package/style/scss/Layout/LayoutInnerColumn.scss +263 -263
- package/style/scss/Layout/LayoutProject.scss +126 -126
- package/style/scss/Layout/LayoutSinglePage.scss +17 -17
- package/style/scss/Layout/LayoutTwoColumn.scss +60 -60
- package/style/scss/Settings/_Mixins.scss +232 -232
- package/style/scss/Settings/_MobileVariables.scss +11 -11
- package/style/scss/Settings/_bs-variables-dark.scss +70 -70
- package/style/scss/Settings/_bs-variables.scss +1743 -1743
- package/style/scss/Settings/_color-mode.scss +122 -122
- package/style/scss/Settings/_custom-variables.scss +10 -10
- package/tagEditor.vue +249 -249
- package/tree.vue +71 -71
- package/treeItem.vue +358 -358
- package/vueLoadingOverlay.vue +74 -74
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bg-gray-000 sticky-top d-print-none">
|
|
3
|
+
<nav class="navbar navbar-main navbar-expand-lg border-bottoms py-0" data-bs-theme="dark">
|
|
4
|
+
<div class="navbar-placeholder-content px-4 placeholder-glow">
|
|
5
|
+
<span class="placeholder w-1rem"></span>
|
|
6
|
+
<span class="placeholder w-20rem"></span>
|
|
7
|
+
<span class="placeholder w-5rem"></span>
|
|
8
|
+
<span class="placeholder w-5rem"></span>
|
|
9
|
+
<span class="placeholder w-5rem"></span>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="navbar-content opacity-0 d-flex align-items-center flex-fill w-100">
|
|
12
|
+
<div class="border-end">
|
|
13
|
+
<a :href="arrowBackLink" class="btn btn-normal btn-square" title="離開專案"><span
|
|
14
|
+
class="material-icons">home</span></a>
|
|
15
|
+
</div>
|
|
16
|
+
<span class="fs-6 mb-0 mx-4 text-nowrap text-project-title text-overflow"><b
|
|
17
|
+
class="">{{projectInfo?.name}}</b></span>
|
|
18
|
+
<!--TODO: 解決 overflow scroll 與 dropdown 衝突-->
|
|
19
|
+
<div class="flex-grow-1 text-nowrap">
|
|
20
|
+
<div class="d-flex flex-grow-1 border-start">
|
|
21
|
+
<nav class="navbar-nav navbar-main navbar-tab navbar-line navbar-line-lg">
|
|
22
|
+
<div class="nav-item navbar-line-item btn nav-link border-0 dropdown"
|
|
23
|
+
:class="{'active': isActive(null)}">
|
|
24
|
+
<a class="dropdown-link"
|
|
25
|
+
:href="finalRootDomain + '/ProjectManagement/ProjectInfo?id=' + projectId">
|
|
26
|
+
專案資訊
|
|
27
|
+
</a>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="nav-item navbar-line-item btn nav-link border-0 dropdown"
|
|
30
|
+
:class="{'active': isActive(navLinkObj.moduleLink)}">
|
|
31
|
+
<!-- NOTE 自己的獨立AP 沒有list,目前因為隕石已被GeneralLink取代 -->
|
|
32
|
+
<!-- <a :href="navLinkObj.url + projectId" class="dropdown-link" v-if="navLinkObj?.moduleLink?.selfIsApp">
|
|
33
|
+
<span class="material-icons icon-18 me-2">{{ navLinkObj?.moduleLink?.icon }}</span>
|
|
34
|
+
{{ navLinkObj?.moduleLink?.name }}
|
|
35
|
+
</a> -->
|
|
36
|
+
<span class="dropdown-link dropdown-toggle" data-bs-toggle="dropdown"
|
|
37
|
+
aria-expanded="false">
|
|
38
|
+
<span class="material-icons icon-18 icon-shine me-1">{{ navLinkObj?.iconName
|
|
39
|
+
}}</span>
|
|
40
|
+
功能選單
|
|
41
|
+
</span>
|
|
42
|
+
<ul class="dropdown-menu" :class="{ 'p-0': navLinkObj?.featurePackApps?.length == 0 }">
|
|
43
|
+
<li v-if="navLinkObj?.featurePackApps?.length > 0">
|
|
44
|
+
<a class="dropdown-item" :href="app.url + '?projectId=' + projectId"
|
|
45
|
+
v-for="(app, index) in navLinkObj.featurePackApps" :key="index">
|
|
46
|
+
<span class="material-icons icon-18 align-middle me-2">{{app.iconName}}</span>
|
|
47
|
+
<span class="align-middle">{{app.name}}</span>
|
|
48
|
+
</a>
|
|
49
|
+
</li>
|
|
50
|
+
</ul>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="nav-item navbar-line-item btn nav-link border-0 dropdown"
|
|
53
|
+
:class="{'active': isActive(item.id)}" v-for="item in navLinkObj.generalLinks">
|
|
54
|
+
<a :href="item.url + '?projectId=' + projectId" class="dropdown-link">
|
|
55
|
+
<span class="material-icons icon-18 me-2">{{item.iconName}}</span>
|
|
56
|
+
{{item.name}}
|
|
57
|
+
</a>
|
|
58
|
+
</div>
|
|
59
|
+
</nav>
|
|
60
|
+
<nav class="navbar-nav navbar-main navbar-line navbar-line-lg ms-auto">
|
|
61
|
+
<div class="nav-item navbar-line-item btn nav-link border-0">
|
|
62
|
+
<a href="https://docs.jobdone.cc/" target="_blank">
|
|
63
|
+
<span class="align-middle">使用指南</span>
|
|
64
|
+
<span class="material-icons icon-18 align-middle icon-help ms-1">help</span>
|
|
65
|
+
</a>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="nav-item navbar-line-item btn nav-link border-0 dropdown">
|
|
68
|
+
<span class="dropdown-link dropdown-toggle" data-bs-toggle="dropdown"
|
|
69
|
+
aria-expanded="false">
|
|
70
|
+
<div class="thumbnail-content thumbnail-32 rounded-circle me-2"
|
|
71
|
+
:style="'background-image: url(' + userPicture + ');'"></div>
|
|
72
|
+
{{userId}}
|
|
73
|
+
</span>
|
|
74
|
+
<ul class="dropdown-menu dropdown-menu-end">
|
|
75
|
+
<li>
|
|
76
|
+
<a class="dropdown-item" :href="finalRootDomain + '/Profile'">個人資訊</a>
|
|
77
|
+
</li>
|
|
78
|
+
<li>
|
|
79
|
+
<hr class="dropdown-divider">
|
|
80
|
+
</li>
|
|
81
|
+
<li>
|
|
82
|
+
<a class="dropdown-item" :href="logOutLink">登出</a>
|
|
83
|
+
</li>
|
|
84
|
+
</ul>
|
|
85
|
+
</div>
|
|
86
|
+
</nav>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</nav>
|
|
91
|
+
<div
|
|
92
|
+
class="info-project bg-primary bg-opacity-25 border-top border-bottom border-primary border-opacity-25 py-2">
|
|
93
|
+
<div class="navbar-placeholder-content px-5 placeholder-glow">
|
|
94
|
+
<span class="placeholder placeholder-xs w-10rem ms-4"></span>
|
|
95
|
+
<span class="placeholder placeholder-xs w-12rem"></span>
|
|
96
|
+
<span class="placeholder placeholder-xs w-6rem"></span>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="navbar-content opacity-0 d-flex align-items-center">
|
|
99
|
+
<span class="badge badge-outline-purple me-3">{{ navLinkObj?.moduleLink?.name }}</span>
|
|
100
|
+
<small class="d-flex me-4" v-if="projectInfo?.caseNo">
|
|
101
|
+
<b class="me-2">案號</b>
|
|
102
|
+
<span>{{projectInfo?.caseNo}}</span>
|
|
103
|
+
</small>
|
|
104
|
+
<small class="d-flex me-4">
|
|
105
|
+
<b class="me-2">開工/完工日期</b>
|
|
106
|
+
<span>{{formatDate(projectInfo?.beginDT)}} - {{formatDate(projectInfo?.endDT)}}</span>
|
|
107
|
+
</small>
|
|
108
|
+
<small class="d-flex me-4">
|
|
109
|
+
<b class="me-2">核定工期</b>
|
|
110
|
+
<span>{{projectInfo?.approvedWorkingPeriod}}天</span>
|
|
111
|
+
</small>
|
|
112
|
+
<small class="d-flex" v-if="projectInfo?.extendToDT">
|
|
113
|
+
<b class="me-2">展延至</b>
|
|
114
|
+
<span>{{ formatDate(projectInfo?.extendToDT) }} ({{projectInfo?.extendDays}}天)</span>
|
|
115
|
+
</small>
|
|
116
|
+
<small class="d-flex ms-auto">
|
|
117
|
+
<slot></slot>
|
|
118
|
+
</small>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</template>
|
|
123
|
+
|
|
124
|
+
<script>
|
|
125
|
+
import { formatDate } from '../../../node_modules/jobdone-shared-files/common/format';
|
|
126
|
+
import { onMounted, ref, computed, nextTick } from 'vue';
|
|
127
|
+
import axios from 'axios';
|
|
128
|
+
import '../../bootstrap/js/dist/dropdown.js';
|
|
129
|
+
|
|
130
|
+
export default {
|
|
131
|
+
props: {
|
|
132
|
+
arrowBackLink: {
|
|
133
|
+
type: String,
|
|
134
|
+
required: true
|
|
135
|
+
},
|
|
136
|
+
projectId: {
|
|
137
|
+
type: String,
|
|
138
|
+
required: true
|
|
139
|
+
},
|
|
140
|
+
projectInfo: {
|
|
141
|
+
type: [String, Object],
|
|
142
|
+
required: true
|
|
143
|
+
},
|
|
144
|
+
projectApps: {
|
|
145
|
+
type: [String, Object],
|
|
146
|
+
required: true
|
|
147
|
+
},
|
|
148
|
+
activeClientId: {
|
|
149
|
+
type: String,
|
|
150
|
+
required: false,
|
|
151
|
+
},
|
|
152
|
+
rootDomain: {
|
|
153
|
+
type: String,
|
|
154
|
+
required: true
|
|
155
|
+
},
|
|
156
|
+
userId: {
|
|
157
|
+
type: String,
|
|
158
|
+
required: true
|
|
159
|
+
},
|
|
160
|
+
userPicture: {
|
|
161
|
+
type: String,
|
|
162
|
+
required: true
|
|
163
|
+
},
|
|
164
|
+
logOutLink: {
|
|
165
|
+
type: String,
|
|
166
|
+
required: true
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
setup(props) {
|
|
170
|
+
const projectInfo = ref({});
|
|
171
|
+
const navLinkObj = ref({});
|
|
172
|
+
const finalRootDomain = computed(() => {
|
|
173
|
+
if (props.rootDomain.substr(-1) === "/") {
|
|
174
|
+
return props.rootDomain.slice(0, -1);
|
|
175
|
+
}
|
|
176
|
+
return props.rootDomain;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const isActive = (target) => {
|
|
180
|
+
if (target === null) {
|
|
181
|
+
// 專案資訊
|
|
182
|
+
return target === null && !props.activeClientId;
|
|
183
|
+
}
|
|
184
|
+
if (typeof target === 'object') {
|
|
185
|
+
// 功能選單
|
|
186
|
+
return !!props.activeClientId && (target.clientId === props.activeClientId || target.apps.some(x => x.clientId == props.activeClientId))
|
|
187
|
+
}
|
|
188
|
+
if (!!props.activeClientId && target == props.activeClientId) {
|
|
189
|
+
// 功能選單
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
onMounted(async () => {
|
|
196
|
+
try {
|
|
197
|
+
switch (typeof props.projectInfo) {
|
|
198
|
+
case 'string':
|
|
199
|
+
axios.get(props.projectInfo).then((res) => {
|
|
200
|
+
projectInfo.value = res.data;
|
|
201
|
+
});
|
|
202
|
+
break;
|
|
203
|
+
case 'object':
|
|
204
|
+
projectInfo.value = props.projectInfo;
|
|
205
|
+
break;
|
|
206
|
+
default:
|
|
207
|
+
projectInfo.value = {
|
|
208
|
+
caseNo: '',
|
|
209
|
+
name: '',
|
|
210
|
+
beginDT: '',
|
|
211
|
+
endDT: '',
|
|
212
|
+
approvedWorkingPeriod: '',
|
|
213
|
+
extendToDT: '',
|
|
214
|
+
extendDays: ''
|
|
215
|
+
};
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
} catch (e) {
|
|
219
|
+
projectInfo.value = {
|
|
220
|
+
caseNo: '',
|
|
221
|
+
name: '',
|
|
222
|
+
beginDT: '',
|
|
223
|
+
endDT: '',
|
|
224
|
+
approvedWorkingPeriod: '',
|
|
225
|
+
extendToDT: '',
|
|
226
|
+
extendDays: ''
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
switch (typeof props.projectApps) {
|
|
231
|
+
case 'string':
|
|
232
|
+
axios.get(props.projectApps).then((res) => {
|
|
233
|
+
navLinkObj.value = res.data;
|
|
234
|
+
});
|
|
235
|
+
break;
|
|
236
|
+
case 'object':
|
|
237
|
+
navLinkObj.value = props.projectApps;
|
|
238
|
+
break;
|
|
239
|
+
default:
|
|
240
|
+
navLinkObj.value = {
|
|
241
|
+
id: null,
|
|
242
|
+
name: '',
|
|
243
|
+
iconName: '',
|
|
244
|
+
featurePackApps: [],
|
|
245
|
+
generalLinks: []
|
|
246
|
+
}
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
} catch (e) {
|
|
250
|
+
navLinkObj.value = {
|
|
251
|
+
id: null,
|
|
252
|
+
name: '',
|
|
253
|
+
iconName: '',
|
|
254
|
+
featurePackApps: [],
|
|
255
|
+
generalLinks: []
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
nextTick(() => {
|
|
261
|
+
let navbarElements = document.getElementsByClassName('navbar-content');
|
|
262
|
+
Array.from(navbarElements).forEach(function (item) {
|
|
263
|
+
item.classList.remove("opacity-0");
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
let placeholderElements = document.getElementsByClassName('navbar-placeholder-content');
|
|
267
|
+
Array.from(placeholderElements).forEach(function (item) {
|
|
268
|
+
item.classList.add("opacity-0");
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
formatDate,
|
|
276
|
+
projectInfo,
|
|
277
|
+
navLinkObj,
|
|
278
|
+
finalRootDomain,
|
|
279
|
+
isActive
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
</script>
|
|
284
|
+
|
|
285
|
+
<style scoped lang="scss">
|
|
286
|
+
@import "../../bootstrap/scss/functions";
|
|
287
|
+
@import "../../bootstrap/scss/mixins";
|
|
288
|
+
@import "../style/scss/Settings/bs-variables";
|
|
289
|
+
@import "../style/scss/Settings/Mixins";
|
|
290
|
+
|
|
291
|
+
.navbar-content{
|
|
292
|
+
transition: .5s;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.navbar-placeholder-content{
|
|
296
|
+
@include position-center();
|
|
297
|
+
display: flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
gap: 1rem;
|
|
300
|
+
mix-blend-mode: color-burn;
|
|
301
|
+
pointer-events: none;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.text-project-title {
|
|
305
|
+
color: var(--dark-theme-primary);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.navbar[data-bs-theme="dark"] {
|
|
309
|
+
--bs-body-color: var(--gray-500);
|
|
310
|
+
color: var(--bs-body-color);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.navbar-main {
|
|
314
|
+
.navbar-line-item {
|
|
315
|
+
--bs-navbar-nav-link-padding-x: 1rem;
|
|
316
|
+
}
|
|
317
|
+
.dropdown-menu {
|
|
318
|
+
max-height: 80vh;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
.navbar[data-bs-theme="dark"], .navbar-main {
|
|
324
|
+
background-color: var(--gray-900);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.navbar-line-item.active {
|
|
328
|
+
background-color: var(--gray-800);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.navbar-tab{
|
|
332
|
+
min-height: 60px;
|
|
333
|
+
padding-top: 0.75rem;
|
|
334
|
+
padding-left: 0.5rem;
|
|
335
|
+
.navbar-line-item{
|
|
336
|
+
min-height: auto;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.navbar-line-item.dropdown .dropdown-menu {
|
|
341
|
+
z-index: $zindex-sticky + 1;
|
|
342
|
+
}
|
|
343
|
+
.navbar-line-item.dropdown .dropdown-toggle[aria-expanded=true]{
|
|
344
|
+
color: $white;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.info-project {
|
|
348
|
+
position: relative;
|
|
349
|
+
padding-left: 60px;
|
|
350
|
+
padding-right: 1rem;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.icon-shine{
|
|
354
|
+
background: linear-gradient(120deg, #fff 20%, #24BCE7 40%, #e8ecff 45%, #5872ff 60%, #fff 90%);
|
|
355
|
+
-webkit-background-clip: text;
|
|
356
|
+
color: transparent;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.icon-help{
|
|
360
|
+
color: #c8d1ff;
|
|
361
|
+
}
|
|
362
|
+
</style>
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import OOXX from '../../node_modules/jobdone-shared-files/OOXX.vue';
|
|
7
7
|
```
|
|
8
8
|
### .
|
|
9
|
-
## 01.ProjectManagement/projectNavbar - 專案資訊Navbar
|
|
9
|
+
## 01.ProjectManagement/projectNavbar - 專案資訊Navbar(2024.07.30_v2版本為破壞性更新)
|
|
10
10
|
|
|
11
11
|
### 需要傳入的值:
|
|
12
12
|
| 數值名稱 | 說明 | 必要 |
|
|
@@ -260,11 +260,11 @@ import OOXX from '../../node_modules/jobdone-shared-files/OOXX.vue';
|
|
|
260
260
|
<autocomplete-select
|
|
261
261
|
:selected-data="selected"
|
|
262
262
|
:opts="members"
|
|
263
|
-
:filter-keys="['firstName','lastName','enName']"
|
|
264
|
-
preview-key="enName + ' ( ' + lastName + ' ' + firstName + ' ) '"
|
|
263
|
+
:filter-keys="['firstName','lastName','enName']"
|
|
265
264
|
binding-key="id"
|
|
266
265
|
@select="(v) => selected = v.id"
|
|
267
266
|
:html-option='true'
|
|
267
|
+
opt-class='border-bottom'
|
|
268
268
|
>
|
|
269
269
|
<template #option = "{ optData }">
|
|
270
270
|
<div>我全要喵喵喵喵!!</div>
|
|
@@ -303,11 +303,12 @@ import OOXX from '../../node_modules/jobdone-shared-files/OOXX.vue';
|
|
|
303
303
|
| # | 參數 Attribute | 型別 Type | 預設值 Default | 選項 Option | 說明 Description |
|
|
304
304
|
| --- | ----------------- | --------- | -------------- | ----------------------------------------- | --------------- |
|
|
305
305
|
| 1 | `selected-data` | `String` `Number` `Object` | `none` | | 當前選擇的值(類似平常`vModel`的用法) |
|
|
306
|
-
| 2 | `opts` | `Array` | `[]` | | 選項列表,只接受`StringArray` `NumberArray` `ObjectArray
|
|
307
|
-
| 3 | `
|
|
308
|
-
| 4 | `
|
|
309
|
-
| 5 | `
|
|
310
|
-
| 6 | `
|
|
306
|
+
| 2 | `opts` | `Array` | `[]` | | 選項列表,只接受`StringArray` `NumberArray` `ObjectArray`,且請陣列內容格式統一 |
|
|
307
|
+
| 3 | `opt-class` | `String` | `[]` | `''`| 選項列表客製化樣式
|
|
308
|
+
| 4 | `placeholder` | `String` | `'請選擇'` | | 未選擇內容時的提示文字 |
|
|
309
|
+
| 5 | `search-placeholder` | `String` | `''` | | 自定義搜尋框的提示文字。如未設定,有選擇內容時會將選擇的內容當成提示文字,而未選擇時則顯示placeholder(參數3)的值 |
|
|
310
|
+
| 6 | `trigger-class` | `String` | `''` | | 預覽框與輸入框的樣式CLSS,可用於驗證提示 |
|
|
311
|
+
| 7 | `list-put` | `String`| `'body'` | | 列表Dom放置位置 |
|
|
311
312
|
|
|
312
313
|
### 清除按鈕參數
|
|
313
314
|
| # | 參數 Attribute | 型別 Type | 預設值 Default | 選項 Option | 說明 Description |
|