jobdone-shared-files 1.0.42 → 1.0.44

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 (39) hide show
  1. package/ModuleInfo/LayoutNav.vue +251 -251
  2. package/ModuleInfo/logo-with-text.svg +22 -22
  3. package/ModuleInfo/navButton.vue +218 -218
  4. package/ProjectManagement/projectNavbar.vue +363 -363
  5. package/README.md +0 -1
  6. package/autocompleteSelect.vue +467 -465
  7. package/common/directives/collapse.js +12 -12
  8. package/common/directives/popovers.js +10 -10
  9. package/common/directives/selectPlaceholder.js +52 -52
  10. package/common/directives/textareaAutoHeight.js +10 -10
  11. package/common/directives/tooltip.js +10 -10
  12. package/common/format.js +26 -26
  13. package/index.js +14 -14
  14. package/lightboxWithOverview.vue +156 -156
  15. package/package.json +19 -19
  16. package/paginate.vue +141 -141
  17. package/style/css/vue-loading-overlay/index.css +40 -40
  18. package/style/scss/Common/Animation.scss +9 -9
  19. package/style/scss/Common/SelectableTable.scss +36 -36
  20. package/style/scss/Common/filepond.scss +31 -31
  21. package/style/scss/Common/thumbnail-group.scss +14 -14
  22. package/style/scss/Layout/LayoutBase.scss +1032 -1032
  23. package/style/scss/Layout/LayoutInnerColumn.scss +263 -263
  24. package/style/scss/Layout/LayoutProject.scss +126 -126
  25. package/style/scss/Layout/LayoutSinglePage.scss +17 -17
  26. package/style/scss/Layout/LayoutTwoColumn.scss +60 -60
  27. package/style/scss/Settings/_Mixins.scss +232 -232
  28. package/style/scss/Settings/_MobileVariables.scss +11 -11
  29. package/style/scss/Settings/_bs-variables-dark.scss +70 -70
  30. package/style/scss/Settings/_bs-variables.scss +1743 -1743
  31. package/style/scss/Settings/_color-mode.scss +122 -122
  32. package/style/scss/Settings/_custom-variables.scss +10 -10
  33. package/tagEditor.vue +249 -249
  34. package/tree.vue +71 -71
  35. package/treeItem.vue +358 -358
  36. package/vueLoadingOverlay.vue +74 -74
  37. package/style/scss/Common/Tree.scss +0 -282
  38. package/treeItemV2.vue +0 -79
  39. package/treeV2.vue +0 -71
package/tagEditor.vue CHANGED
@@ -1,250 +1,250 @@
1
- <template>
2
- <div class="tag-editor" v-if="tagAry">
3
- <div class="main-cont">
4
- <div class="form-control form-control-sm" :class="disabled ? 'is-disabled' : ''">
5
- <template v-if="tagAry.length">
6
- <div class="badge rounded-pill" :class="disabled ? 'badge-outline-gray ' : 'badge-outline-purple'"
7
- v-for="(tag, index) in tagAry" :key="index" :title="tag">
8
- <div class="tag-text">{{ tag }}</div>
9
- <div class="remove-btn-box" v-if="!disabled">
10
- <button type="button" class="remove-btn" @click="removeTag(index)"><span
11
- class="material-icons">close</span>
12
- </button>
13
- </div>
14
- </div>
15
- </template>
16
- <input v-if="!disabled" class="new-tag-input" list="datalistOptions" type="text" :placeholder="placeholder"
17
- v-model.trim="newTag" @keydown.enter="addTag" @keyup="keyupFunction">
18
- <datalist id="datalistOptions" v-if="autoCompleteShow">
19
- <option :value="opt" v-for="(opt, idx) in autoCompleteOption" :key="idx">{{ opt }}</option>
20
- </datalist>
21
- </div>
22
- </div>
23
- <div class="helper-text-box" v-if="!disabled">
24
- <small class="helper-text">在輸入框中輸入文字後,按下鍵盤的"Enter"鍵,即可增加標籤。(標籤僅接受中文、英文、數字、下底線)</small>
25
- </div>
26
- </div>
27
- </template>
28
- <script>
29
- import { ref, reactive, onMounted, computed } from 'vue'
30
-
31
- export default {
32
- props: {
33
- defaultTagList: {
34
- type: Array,
35
- default: () => []
36
- },
37
- placeholder: {
38
- type: String,
39
- default: '請在此處輸入標籤文字'
40
- },
41
- autoComplete: {
42
- type: Boolean,
43
- default: true
44
- },
45
- autoCompleteOption: {
46
- type: Array,
47
- default: () => []
48
- },
49
- disabled: {
50
- type: Boolean,
51
- default: false
52
- }
53
- },
54
- setup(props, { emit }) {
55
- // 基本資料
56
- const tagAry = reactive([])
57
- const newTag = ref('')
58
-
59
- const autoCompleteShow = computed(() => {
60
- let show = props.autoComplete
61
- if (!newTag.value || props.autoCompleteOption.length < 1) {
62
- show = false
63
- }
64
- return show
65
- })
66
- // 輸入時 AutoComplete
67
- var autoCompleteTimer
68
- function updateAutoCompleteOption() {
69
- clearTimeout(autoCompleteTimer);
70
- if (newTag.value) {
71
- autoCompleteTimer = setTimeout(() => {
72
- emit('update-auto-complete-option', newTag.value);
73
- }, 500);
74
- }
75
- }
76
-
77
- // 刷新預設選中內容
78
- function getDefaultTag(updateData = []) {
79
- tagAry.splice(0, tagAry.length, ...updateData)
80
- }
81
- function keyupFunction() {
82
- if (props.autoCompleteOption) {
83
- updateAutoCompleteOption()
84
- }
85
- newTag.value = newTag.value.replace(/[^\a-\z\A-\Z0-9\u4E00-\u9FA5]/g, '_')
86
- }
87
-
88
- // 重複標籤禁止新增
89
- var isDuplicate = computed(() => {
90
- return newTag.value ? !!tagAry.find(tag => tag == newTag.value) : false
91
- })
92
-
93
- // 增加Tag
94
- function addTag() {
95
- if (newTag.value && !isDuplicate.value) {
96
- tagAry.push(newTag.value)
97
- }
98
- newTag.value = ''
99
- }
100
- // 移除Tag
101
- function removeTag(index) {
102
- tagAry.splice(index, 1)
103
- }
104
- function reset() {
105
- tagAry.splice(0, tagAry.length)
106
- newTag.value = ''
107
- }
108
-
109
- onMounted(() => {
110
- getDefaultTag(props.defaultTagList)
111
- })
112
- return {
113
- tagAry,
114
- newTag,
115
- addTag,
116
- removeTag,
117
- updateAutoCompleteOption,
118
- autoCompleteTimer,
119
- autoCompleteShow,
120
- reset,
121
- keyupFunction,
122
- isDuplicate,
123
- getDefaultTag
124
- }
125
- }
126
- }
127
- </script>
128
-
129
- <style lang="scss" scoped>
130
- .tag-editor {
131
- background: var(--bs-gray-100);
132
- border-radius: var(--bs-border-radius);
133
- padding: .5rem;
134
-
135
- .helper-text-box {
136
- text-align: start;
137
-
138
- .helper-text {
139
- font-size: 0.75rem;
140
- color: var(--bs-gray-500);
141
- }
142
- }
143
-
144
- .main-cont {
145
- position: relative;
146
-
147
- .auto-complete-box {
148
- all: unset;
149
- display: none;
150
- visibility: hidden;
151
- position: absolute;
152
- width: 90%;
153
- overflow: hidden;
154
-
155
- &.show {
156
- visibility: visible;
157
- display: block;
158
- position: absolute;
159
- top: calc(100% + 0.25rem);
160
- background: #fff;
161
- border: 1px solid var(--bs-gray-300);
162
- border-radius: var(--bs-border-radius);
163
- box-shadow: var(--bs-box-shadow);
164
- }
165
-
166
- .opt-item {
167
- padding: 0.5rem;
168
- cursor: pointer;
169
- overflow: hidden;
170
- text-overflow: ellipsis;
171
-
172
- &:not(:last-child) {
173
- border-bottom: 1px solid var(--bs-gray-300);
174
- }
175
- }
176
- }
177
- }
178
-
179
- .form-control {
180
- display: flex;
181
- align-items: center;
182
- flex-wrap: wrap;
183
- padding: .5rem .5rem .25rem .5rem;
184
-
185
- &.is-disabled:hover {
186
- cursor: not-allowed;
187
- }
188
- }
189
-
190
- .new-tag-input {
191
- all: unset;
192
- flex-grow: 1;
193
- margin-bottom: .25rem;
194
- background: var(--bs-gray-100);
195
- padding: .25rem .75rem;
196
- border-radius: 99px;
197
- border: 1px solid rgba(#000, 0);
198
- }
199
-
200
- .badge.rounded-pill {
201
- margin: 0 .25rem .25rem 0;
202
- display: inline-flex;
203
- align-items: stretch;
204
- overflow: hidden;
205
-
206
- .tag-text {
207
- margin: auto;
208
- overflow: hidden;
209
- text-overflow: ellipsis;
210
- }
211
-
212
- .remove-btn-box {
213
- display: flex;
214
- align-items: stretch;
215
-
216
- &::before {
217
- display: block;
218
- content: ' ';
219
- height: 100%;
220
- border-left: 1px solid var(--bs-gray-300);
221
- margin: 0 0.25rem;
222
- }
223
- }
224
-
225
- .remove-btn {
226
- all: unset;
227
- display: flex;
228
- align-items: center;
229
- justify-content: center;
230
-
231
- .material-icons {
232
- font-size: 16px;
233
- line-height: 16px;
234
- color: var(--bs-purple);
235
- opacity: .5;
236
- transition: .3s;
237
- }
238
-
239
- &:hover {
240
- cursor: pointer;
241
-
242
- .material-icons {
243
- opacity: 1;
244
- }
245
- }
246
- }
247
- }
248
-
249
- }
1
+ <template>
2
+ <div class="tag-editor" v-if="tagAry">
3
+ <div class="main-cont">
4
+ <div class="form-control form-control-sm" :class="disabled ? 'is-disabled' : ''">
5
+ <template v-if="tagAry.length">
6
+ <div class="badge rounded-pill" :class="disabled ? 'badge-outline-gray ' : 'badge-outline-purple'"
7
+ v-for="(tag, index) in tagAry" :key="index" :title="tag">
8
+ <div class="tag-text">{{ tag }}</div>
9
+ <div class="remove-btn-box" v-if="!disabled">
10
+ <button type="button" class="remove-btn" @click="removeTag(index)"><span
11
+ class="material-icons">close</span>
12
+ </button>
13
+ </div>
14
+ </div>
15
+ </template>
16
+ <input v-if="!disabled" class="new-tag-input" list="datalistOptions" type="text" :placeholder="placeholder"
17
+ v-model.trim="newTag" @keydown.enter="addTag" @keyup="keyupFunction">
18
+ <datalist id="datalistOptions" v-if="autoCompleteShow">
19
+ <option :value="opt" v-for="(opt, idx) in autoCompleteOption" :key="idx">{{ opt }}</option>
20
+ </datalist>
21
+ </div>
22
+ </div>
23
+ <div class="helper-text-box" v-if="!disabled">
24
+ <small class="helper-text">在輸入框中輸入文字後,按下鍵盤的"Enter"鍵,即可增加標籤。(標籤僅接受中文、英文、數字、下底線)</small>
25
+ </div>
26
+ </div>
27
+ </template>
28
+ <script>
29
+ import { ref, reactive, onMounted, computed } from 'vue'
30
+
31
+ export default {
32
+ props: {
33
+ defaultTagList: {
34
+ type: Array,
35
+ default: () => []
36
+ },
37
+ placeholder: {
38
+ type: String,
39
+ default: '請在此處輸入標籤文字'
40
+ },
41
+ autoComplete: {
42
+ type: Boolean,
43
+ default: true
44
+ },
45
+ autoCompleteOption: {
46
+ type: Array,
47
+ default: () => []
48
+ },
49
+ disabled: {
50
+ type: Boolean,
51
+ default: false
52
+ }
53
+ },
54
+ setup(props, { emit }) {
55
+ // 基本資料
56
+ const tagAry = reactive([])
57
+ const newTag = ref('')
58
+
59
+ const autoCompleteShow = computed(() => {
60
+ let show = props.autoComplete
61
+ if (!newTag.value || props.autoCompleteOption.length < 1) {
62
+ show = false
63
+ }
64
+ return show
65
+ })
66
+ // 輸入時 AutoComplete
67
+ var autoCompleteTimer
68
+ function updateAutoCompleteOption() {
69
+ clearTimeout(autoCompleteTimer);
70
+ if (newTag.value) {
71
+ autoCompleteTimer = setTimeout(() => {
72
+ emit('update-auto-complete-option', newTag.value);
73
+ }, 500);
74
+ }
75
+ }
76
+
77
+ // 刷新預設選中內容
78
+ function getDefaultTag(updateData = []) {
79
+ tagAry.splice(0, tagAry.length, ...updateData)
80
+ }
81
+ function keyupFunction() {
82
+ if (props.autoCompleteOption) {
83
+ updateAutoCompleteOption()
84
+ }
85
+ newTag.value = newTag.value.replace(/[^\a-\z\A-\Z0-9\u4E00-\u9FA5]/g, '_')
86
+ }
87
+
88
+ // 重複標籤禁止新增
89
+ var isDuplicate = computed(() => {
90
+ return newTag.value ? !!tagAry.find(tag => tag == newTag.value) : false
91
+ })
92
+
93
+ // 增加Tag
94
+ function addTag() {
95
+ if (newTag.value && !isDuplicate.value) {
96
+ tagAry.push(newTag.value)
97
+ }
98
+ newTag.value = ''
99
+ }
100
+ // 移除Tag
101
+ function removeTag(index) {
102
+ tagAry.splice(index, 1)
103
+ }
104
+ function reset() {
105
+ tagAry.splice(0, tagAry.length)
106
+ newTag.value = ''
107
+ }
108
+
109
+ onMounted(() => {
110
+ getDefaultTag(props.defaultTagList)
111
+ })
112
+ return {
113
+ tagAry,
114
+ newTag,
115
+ addTag,
116
+ removeTag,
117
+ updateAutoCompleteOption,
118
+ autoCompleteTimer,
119
+ autoCompleteShow,
120
+ reset,
121
+ keyupFunction,
122
+ isDuplicate,
123
+ getDefaultTag
124
+ }
125
+ }
126
+ }
127
+ </script>
128
+
129
+ <style lang="scss" scoped>
130
+ .tag-editor {
131
+ background: var(--bs-gray-100);
132
+ border-radius: var(--bs-border-radius);
133
+ padding: .5rem;
134
+
135
+ .helper-text-box {
136
+ text-align: start;
137
+
138
+ .helper-text {
139
+ font-size: 0.75rem;
140
+ color: var(--bs-gray-500);
141
+ }
142
+ }
143
+
144
+ .main-cont {
145
+ position: relative;
146
+
147
+ .auto-complete-box {
148
+ all: unset;
149
+ display: none;
150
+ visibility: hidden;
151
+ position: absolute;
152
+ width: 90%;
153
+ overflow: hidden;
154
+
155
+ &.show {
156
+ visibility: visible;
157
+ display: block;
158
+ position: absolute;
159
+ top: calc(100% + 0.25rem);
160
+ background: #fff;
161
+ border: 1px solid var(--bs-gray-300);
162
+ border-radius: var(--bs-border-radius);
163
+ box-shadow: var(--bs-box-shadow);
164
+ }
165
+
166
+ .opt-item {
167
+ padding: 0.5rem;
168
+ cursor: pointer;
169
+ overflow: hidden;
170
+ text-overflow: ellipsis;
171
+
172
+ &:not(:last-child) {
173
+ border-bottom: 1px solid var(--bs-gray-300);
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ .form-control {
180
+ display: flex;
181
+ align-items: center;
182
+ flex-wrap: wrap;
183
+ padding: .5rem .5rem .25rem .5rem;
184
+
185
+ &.is-disabled:hover {
186
+ cursor: not-allowed;
187
+ }
188
+ }
189
+
190
+ .new-tag-input {
191
+ all: unset;
192
+ flex-grow: 1;
193
+ margin-bottom: .25rem;
194
+ background: var(--bs-gray-100);
195
+ padding: .25rem .75rem;
196
+ border-radius: 99px;
197
+ border: 1px solid rgba(#000, 0);
198
+ }
199
+
200
+ .badge.rounded-pill {
201
+ margin: 0 .25rem .25rem 0;
202
+ display: inline-flex;
203
+ align-items: stretch;
204
+ overflow: hidden;
205
+
206
+ .tag-text {
207
+ margin: auto;
208
+ overflow: hidden;
209
+ text-overflow: ellipsis;
210
+ }
211
+
212
+ .remove-btn-box {
213
+ display: flex;
214
+ align-items: stretch;
215
+
216
+ &::before {
217
+ display: block;
218
+ content: ' ';
219
+ height: 100%;
220
+ border-left: 1px solid var(--bs-gray-300);
221
+ margin: 0 0.25rem;
222
+ }
223
+ }
224
+
225
+ .remove-btn {
226
+ all: unset;
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: center;
230
+
231
+ .material-icons {
232
+ font-size: 16px;
233
+ line-height: 16px;
234
+ color: var(--bs-purple);
235
+ opacity: .5;
236
+ transition: .3s;
237
+ }
238
+
239
+ &:hover {
240
+ cursor: pointer;
241
+
242
+ .material-icons {
243
+ opacity: 1;
244
+ }
245
+ }
246
+ }
247
+ }
248
+
249
+ }
250
250
  </style>
package/tree.vue CHANGED
@@ -1,71 +1,71 @@
1
- <template>
2
- <form ref="form">
3
- <tree-item v-for="(item, index) in items" :key="item.id" :item="item" :index="index" :click-item="clickItem" :active-id="activeId" :tree-item-class="treeItemClass">
4
- <template v-slot:icon-start>
5
- <slot name="icon-start"></slot>
6
- </template>
7
- <template v-slot:icon="slotProps">
8
- <slot name="icon" :item="slotProps.item"></slot>
9
- </template>
10
- </tree-item>
11
- </form>
12
- </template>
13
-
14
- <script>
15
- import { ref, computed } from 'vue';
16
- import TreeItem from './treeItem.vue';
17
- export default {
18
- props: {
19
- items: {
20
- type: Array,
21
- default: function () {
22
- return [];
23
- }
24
- },
25
- clickItem: {
26
- type: Function
27
- },
28
- size: {
29
- type: String,
30
- default: ""
31
- },
32
- bgColor: {
33
- type: String,
34
- default: ""
35
- }
36
- },
37
- components: {
38
- TreeItem
39
- },
40
- setup(props, { emit }) {
41
- const form = ref(null);
42
- const activeId = ref("");
43
- const clickItem = (item) => {
44
- activeId.value = item.id;
45
- props.clickItem(item);
46
- };
47
- const treeItemClass = computed(() => {
48
- var classList = [];
49
- if (props.size == 'sm') {
50
- classList.push('tree-item-sm');
51
- }
52
- if (props.bgColor == 'white') {
53
- classList.push('tree-item-in-white');
54
- }
55
- return classList;
56
- });
57
- const reset = () => {
58
- activeId.value = "";
59
- };
60
- return {
61
- form: form,
62
- treeItemClass: treeItemClass,
63
- activeId: activeId,
64
- clickItem: clickItem,
65
- reset: reset
66
- };
67
- }
68
- }
69
- </script>
70
- <style>
71
- </style>
1
+ <template>
2
+ <form ref="form">
3
+ <tree-item v-for="(item, index) in items" :key="item.id" :item="item" :index="index" :click-item="clickItem" :active-id="activeId" :tree-item-class="treeItemClass">
4
+ <template v-slot:icon-start>
5
+ <slot name="icon-start"></slot>
6
+ </template>
7
+ <template v-slot:icon="slotProps">
8
+ <slot name="icon" :item="slotProps.item"></slot>
9
+ </template>
10
+ </tree-item>
11
+ </form>
12
+ </template>
13
+
14
+ <script>
15
+ import { ref, computed } from 'vue';
16
+ import TreeItem from './treeItem.vue';
17
+ export default {
18
+ props: {
19
+ items: {
20
+ type: Array,
21
+ default: function () {
22
+ return [];
23
+ }
24
+ },
25
+ clickItem: {
26
+ type: Function
27
+ },
28
+ size: {
29
+ type: String,
30
+ default: ""
31
+ },
32
+ bgColor: {
33
+ type: String,
34
+ default: ""
35
+ }
36
+ },
37
+ components: {
38
+ TreeItem
39
+ },
40
+ setup(props, { emit }) {
41
+ const form = ref(null);
42
+ const activeId = ref("");
43
+ const clickItem = (item) => {
44
+ activeId.value = item.id;
45
+ props.clickItem(item);
46
+ };
47
+ const treeItemClass = computed(() => {
48
+ var classList = [];
49
+ if (props.size == 'sm') {
50
+ classList.push('tree-item-sm');
51
+ }
52
+ if (props.bgColor == 'white') {
53
+ classList.push('tree-item-in-white');
54
+ }
55
+ return classList;
56
+ });
57
+ const reset = () => {
58
+ activeId.value = "";
59
+ };
60
+ return {
61
+ form: form,
62
+ treeItemClass: treeItemClass,
63
+ activeId: activeId,
64
+ clickItem: clickItem,
65
+ reset: reset
66
+ };
67
+ }
68
+ }
69
+ </script>
70
+ <style>
71
+ </style>