quasar-ui-sellmate-ui-kit 3.9.1 → 3.9.3

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": "quasar-ui-sellmate-ui-kit",
3
- "version": "3.9.1",
3
+ "version": "3.9.3",
4
4
  "author": "Sellmate Dev Team <dev@sellmate.co.kr>",
5
5
  "description": "Sellmate UI Kit",
6
6
  "license": "MIT",
@@ -30,3 +30,11 @@ export const minusIcon = 'M2 6H10@@fill:none;stroke:currentColor;stroke-width:0.
30
30
  export const searchIcon = 'M9.16634 3.33325C12.388 3.33325 14.9997 5.94492 14.9997 9.16658C14.9997 12.3882 12.388 14.9999 9.16634 14.9999C5.94468 14.9999 3.33301 12.3882 3.33301 9.16658C3.33301 5.94492 5.94468 3.33325 9.16634 3.33325Z@@fill:none;stroke:#737373;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round;&&M13.5523 13.5526L16.8857 16.8859@@fill:none;stroke:#737373;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round|0 0 20 20';
31
31
  export const imageUploadFilledIcon = 'M0.5 15V3C0.5 1.61929 1.61929 0.5 3 0.5H15C16.3807 0.5 17.5 1.61929 17.5 3V15C17.5 16.3807 16.3807 17.5 15 17.5H3C1.61929 17.5 0.5 16.3807 0.5 15Z@@fill:#222222&&M11.125 5.28125C11.125 6.16145 11.8385 6.875 12.7188 6.875C13.599 6.875 14.3125 6.16145 14.3125 5.28125C14.3125 4.40105 13.599 3.6875 12.7188 3.6875C11.8385 3.6875 11.125 4.40105 11.125 5.28125Z@@fill:white&&M17.5 9.3993V11.4342L14.4626 14.2184C13.7719 14.8516 12.7052 14.8284 12.0426 14.1659L4.92678 7.05C4.82914 6.95237 4.67085 6.95237 4.57322 7.05L0.5 11.1232V9.0019L3.51256 5.98934C4.19598 5.30592 5.30402 5.30592 5.98744 5.98934L13.1033 13.1052C13.1979 13.1998 13.3503 13.2032 13.449 13.1127L17.5 9.3993Z@@fill:white|0 0 18 18';
32
32
  export const clockIcon = 'M12 7V12H17@@fill:none;stroke:currentColor;stroke-width:1.5;&&M12 21C16.9707 21 21 16.9707 21 12C21 7.0293 16.9707 3 12 3C7.0293 3 3 7.0293 3 12C3 16.9707 7.0293 21 12 21Z@@fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round|0 0 24 24';
33
+
34
+ // TODO: icon 변경
35
+ export const tableTreeArrowRight =
36
+ 'M14.75 9.20096C15.75 9.77831 15.75 11.2217 14.75 11.799L8 15.6962C7 16.2735 5.75 15.5518 5.75 14.3971L5.75 6.60288C5.75 5.44818 7 4.7265 8 5.30385L14.75 9.20096Z@fill:currentColor|0 0 20 21';
37
+ export const tableTreeArrowDown =
38
+ 'M10.799 15.75C10.2217 16.75 8.77831 16.75 8.20096 15.75L4.30385 9C3.7265 8 4.44819 6.75 5.60289 6.75L13.3971 6.75C14.5518 6.75 15.2735 8 14.6962 9L10.799 15.75Z@fill:currentColor|0 0 20 21';
39
+ export const path =
40
+ 'M6 1.5V6V8.5C6 9.60457 6.89543 10.5 8 10.5H16@fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round|0 0 20 21';
Binary file
@@ -45,6 +45,12 @@
45
45
  {{ allPlaceholder }}
46
46
  </div>
47
47
  </template>
48
+
49
+ <template #no-option>
50
+ <q-item class="s-select-no-option">
51
+ <q-item-section class="text-grey">{{ noOptionLabel }}</q-item-section>
52
+ </q-item>
53
+ </template>
48
54
  </q-select>
49
55
  </template>
50
56
 
@@ -95,6 +101,10 @@
95
101
  default: () => '',
96
102
  type: String,
97
103
  },
104
+ noOptionLabel: {
105
+ type: String,
106
+ default: '선택지가 없습니다.',
107
+ },
98
108
  },
99
109
  setup(props, { emit }) {
100
110
  const model = ref(props.modelValue);
@@ -118,7 +128,10 @@
118
128
  });
119
129
  } else {
120
130
  nextTick(() => {
121
- if (model.value.length === props.options.length - 1) {
131
+ if (
132
+ props.useAll &&
133
+ model.value.length === props.options.filter(v => !v.category).length - 1
134
+ ) {
122
135
  model.value = props.options.filter(v => !v.category);
123
136
  }
124
137
  });
@@ -133,34 +146,34 @@
133
146
  return value !== 0 && !value;
134
147
  }
135
148
 
136
- watch(
137
- () => props.modelValue,
138
- newModelValue => {
139
- if (props.useAll && newModelValue.length === 1 && checkEmptyValue(newModelValue[0])) {
140
- model.value = props.options.filter(v => !v.category);
141
- return;
142
- }
143
- model.value = newModelValue;
144
- },
145
- );
149
+ // watch(
150
+ // () => props.modelValue,
151
+ // newModelValue => {
152
+ // if (props.useAll && newModelValue.length === 1 && checkEmptyValue(newModelValue[0])) {
153
+ // model.value = props.options.filter(v => !v.category);
154
+ // return;
155
+ // }
156
+ // model.value = newModelValue;
157
+ // },
158
+ // );
146
159
 
147
- watch(
148
- () => props.options,
149
- newOptionValue => {
150
- if (props.useAll) {
151
- model.value = newOptionValue.filter(v => !v.category);
152
- }
153
- },
154
- );
160
+ // watch(
161
+ // () => props.options,
162
+ // newOptionValue => {
163
+ // if (props.useAll) {
164
+ // model.value = newOptionValue.filter(v => !v.category);
165
+ // }
166
+ // },
167
+ // );
155
168
 
156
169
  watch(model, () => {
157
170
  emit('update:modelValue', model.value);
158
171
  });
159
172
 
160
173
  onBeforeMount(() => {
161
- if (props.useAll && props.modelValue.length === 1 && checkEmptyValue(props.modelValue[0])) {
162
- model.value = props.options.filter(v => !v.category);
163
- }
174
+ // if (props.useAll && props.modelValue.length === 1 && checkEmptyValue(props.modelValue[0])) {
175
+ // model.value = props.options.filter(v => !v.category);
176
+ // }
164
177
  });
165
178
 
166
179
  return {
@@ -0,0 +1,223 @@
1
+ <template>
2
+ <q-input
3
+ class="s-year-picker q-pa-none bg-white"
4
+ :class="{ 'has-label': insideLabel }"
5
+ dense
6
+ outlined
7
+ readonly
8
+ no-error-icon
9
+ :disable="isDisable"
10
+ @click="openMenu = true"
11
+ v-model="dateModel"
12
+ >
13
+ <template #before v-if="insideLabel">
14
+ <div class="year-month-picker-label">
15
+ {{ insideLabel }}
16
+ </div>
17
+ </template>
18
+
19
+ <template #prepend>
20
+ <q-icon
21
+ :name="dateRangeIcon"
22
+ size="20px"
23
+ color="Grey_Darken-1"
24
+ class="cursor-pointer"
25
+ @click="openMenu = true"
26
+ />
27
+ </template>
28
+
29
+ <template #default>
30
+ <q-menu
31
+ v-model="openMenu"
32
+ ref="singleMenuRef"
33
+ class="s-date-menu"
34
+ no-focus
35
+ no-refocus
36
+ :offset="[0, 6]"
37
+ no-parent-event
38
+ >
39
+ <q-date
40
+ ref="calendar"
41
+ emit-immediately
42
+ v-model="dateModel"
43
+ minimal
44
+ square
45
+ noUnset
46
+ flat
47
+ years-in-month-view
48
+ :default-view="defaultView"
49
+ color="positive"
50
+ class="q-pa-none"
51
+ :mask="defaultView === 'Years' ? 'YYYY' : 'YYYY-MM'"
52
+ :navigation-min-year-month="minYearMonth"
53
+ :navigation-max-year-month="maxYearMonth"
54
+ @navigation="onNavigation"
55
+ >
56
+ </q-date>
57
+ </q-menu>
58
+ </template>
59
+ </q-input>
60
+ </template>
61
+
62
+ <script>
63
+ import { ref } from 'vue';
64
+ import { QIcon, QInput, QDate, QMenu } from 'quasar';
65
+ import { dateRangeIcon } from '../assets/icons';
66
+ import { useModelBinder } from '../composables/modelBinder';
67
+
68
+ export default {
69
+ name: 'SYearPicker',
70
+ components: {
71
+ QDate,
72
+ QIcon,
73
+ QInput,
74
+ QMenu,
75
+ },
76
+ props: {
77
+ modelValue: {
78
+ type: String,
79
+ },
80
+ defaultView: {
81
+ type: String,
82
+ default: 'Months',
83
+ },
84
+ isDisable: {
85
+ type: Boolean,
86
+ default: false,
87
+ },
88
+ insideLabel: {
89
+ type: String,
90
+ },
91
+ minYearMonth: {
92
+ type: String,
93
+ },
94
+ maxYearMonth: {
95
+ type: String,
96
+ },
97
+ },
98
+
99
+ setup(props, { emit }) {
100
+ const dateModel = useModelBinder(props);
101
+ const openMenu = ref(false);
102
+
103
+ const formatMonth = month => (month < 10 ? `0${month}` : month.toString());
104
+
105
+ function onNavigation(nav) {
106
+ const { defaultView } = props;
107
+ const { year, month } = nav;
108
+
109
+ if (defaultView === 'Years') {
110
+ dateModel.value = year.toString();
111
+ openMenu.value = false;
112
+ } else if (defaultView === 'Months' && month) {
113
+ const modelMonth = Number(dateModel.value.split('-')[1]);
114
+
115
+ if (month !== modelMonth) {
116
+ dateModel.value = `${year}-${formatMonth(month)}`;
117
+ openMenu.value = false;
118
+ }
119
+ }
120
+ }
121
+
122
+ return {
123
+ dateRangeIcon,
124
+ dateModel,
125
+ openMenu,
126
+ onNavigation,
127
+ };
128
+ },
129
+ };
130
+ </script>
131
+
132
+ <style scoped lang="scss">
133
+ @import '../css/quasar.variables.scss';
134
+ .s-year-picker {
135
+ width: fit-content;
136
+ height: $default-height;
137
+ border-radius: 4px;
138
+
139
+ &.has-label {
140
+ :deep(.q-field__inner) {
141
+ .q-field__control {
142
+ border-radius: 0 2px 2px 0 !important;
143
+ }
144
+ }
145
+
146
+ :deep(.q-field__before) {
147
+ height: 100%;
148
+ padding: 4px 12px !important;
149
+ border: 1px solid $Grey_Lighten-1;
150
+ border-right: none;
151
+ border-radius: 2px 0 0 2px;
152
+ background: $Grey_Lighten-5;
153
+
154
+ .year-month-picker-label {
155
+ font-size: $default-font;
156
+ font-weight: $default-font-weight;
157
+ color: $Grey_Darken-4;
158
+ }
159
+ }
160
+ }
161
+
162
+ &.q-field--disabled {
163
+ :deep(.q-field__before) {
164
+ border: 1px solid $Grey_Lighten-2;
165
+ border-right: none;
166
+ }
167
+
168
+ :deep(.q-field__inner) {
169
+ .q-field__control {
170
+ &:after {
171
+ border: 1px solid $Grey_Lighten-2;
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ :deep(.q-field__bottom) {
178
+ display: none;
179
+ }
180
+
181
+ :deep(.q-field__inner) {
182
+ .q-field__control {
183
+ padding: 4px 16px 4px 8px !important;
184
+ height: 100%;
185
+
186
+ .q-field__control-container {
187
+ .q-field__native {
188
+ text-align: center;
189
+ }
190
+ }
191
+
192
+ &:before {
193
+ border-style: solid;
194
+ }
195
+
196
+ &:after {
197
+ border: 1px solid $Grey_Lighten-1;
198
+ box-shadow: none;
199
+ }
200
+
201
+ &:hover,
202
+ &:active {
203
+ background: $Grey_Lighten-5 !important;
204
+ }
205
+
206
+ .q-field__prepend {
207
+ height: 20px;
208
+ }
209
+
210
+ .q-field__append {
211
+ height: 20px;
212
+
213
+ .q-icon {
214
+ margin-right: -8px;
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+ .s-date-menu {
221
+ border-radius: 8px;
222
+ }
223
+ </style>
package/src/vue-plugin.js CHANGED
@@ -37,13 +37,14 @@ import SDateTimePicker from './components/SDateTimePicker.vue';
37
37
  import SDateRange from './components/SDateRange.vue';
38
38
  import SDate from './components/SDate.vue';
39
39
  import SDateAutoRangePicker from './components/SDateAutoRangePicker.vue';
40
+ import SYearMonthPicker from './components/SYearMonthPicker.vue';
40
41
  import Directive from './directives/Directive';
41
42
  import SBadge from './components/SBadge.vue';
42
43
 
43
44
  const version = __UI_VERSION__;
44
45
 
45
46
  function install(app) {
46
- app.component('s-badge', SBadge)
47
+ app.component('s-badge', SBadge);
47
48
  app.component('s-breadcrumbs', SBreadcrumbs);
48
49
  app.component('s-button', SButton);
49
50
  app.component('s-button-group', SButtonGroup);
@@ -82,6 +83,7 @@ function install(app) {
82
83
  app.component('s-date-range', SDateRange);
83
84
  app.component('s-date', SDate);
84
85
  app.component('s-date-auto-range-picker', SDateAutoRangePicker);
86
+ app.component('s-year-month-picker', SYearMonthPicker);
85
87
  }
86
88
 
87
89
  export {
@@ -1,209 +0,0 @@
1
- <template>
2
- <q-table
3
- flat
4
- :separator="separator"
5
- :rows="rows"
6
- :columns="columns"
7
- row-key="id"
8
- :rows-per-page-options="[0]"
9
- hide-bottom
10
- :selected-rows-label="getSelectedString"
11
- selection="multiple"
12
- v-model:selected="selectedItem"
13
- >
14
- <template v-slot:header="props">
15
- <tr>
16
- <th
17
- v-for="col in props.cols"
18
- :key="col.name"
19
- :class="col.align"
20
- >
21
- <span>{{ col.label }}</span>
22
- <q-icon v-if="col.name === 'product_name'" name="info" size="sm" class="cursor-pointer">
23
- <q-popup-proxy>
24
- <q-banner>
25
- 여기는 인포
26
- </q-banner>
27
- </q-popup-proxy>
28
- </q-icon>
29
- </th>
30
- </tr>
31
- </template>
32
-
33
- <template v-slot:body="props">
34
- <tr class="center">
35
- <td class="left">
36
- <q-btn
37
- round
38
- flat
39
- dense
40
- :icon="visibleProduct[props.row.id]? 'arrow_drop_down' : 'arrow_right'"
41
- @click="handleVisibleProduct(props.row.id)"
42
- />
43
- <q-icon class="q-ml-xs q-mr-sm" size="xs" name="folder_open" />
44
- <span class="text-Grey_Lighten-1">{{ props.row.label }}</span>
45
- </td>
46
- <td class="left">{{ props.row.market }}</td>
47
- <td class="text-positive">{{ props.row.product_code }}</td>
48
- <td class="left">
49
- <span style="width: 65px; display: inline-block" class="q-mr-sm">
50
- <q-badge
51
- outline
52
- rounded
53
- :color="stateColor[props.row.state]"
54
- :label="props.row.state"
55
- />
56
- </span>
57
- {{ props.row.product_name }}
58
- </td>
59
- <td>{{ props.row.sale_period }}</td>
60
- <td>{{ props.row.stock }}</td>
61
- </tr>
62
-
63
- <tr
64
- v-show="visibleProduct[props.row.id]"
65
- v-for="(row, i) in props.row.children"
66
- :key="i"
67
- class="background-grey"
68
- >
69
- <td>
70
- <q-btn
71
- class="q-ml-lg"
72
- round
73
- flat
74
- dense
75
- :icon="visibleOption[row.subId] ? 'arrow_drop_down' : 'arrow_right'"
76
- @click="handleVisibleOption(row.subId)"
77
- />
78
- <q-icon class="q-ml-xs q-mr-sm" size="xs" name="folder" />
79
- <span class="text-Grey_Lighten-1">{{ row.label }}</span>
80
- </td>
81
- <td class="left">{{ row.market }}</td>
82
- <td>{{ row.product_code }}</td>
83
- <td class="left">{{ row.state }}{{ row.product_name }}</td>
84
- <td>{{ row.sale_period }}</td>
85
- <td>{{ row.stock }}</td>
86
- </tr>
87
-
88
- <tr
89
- v-show="visibleOption[props.row.id]"
90
- v-for="(row, i) in props.row.children[0].children"
91
- :key="i"
92
- class="background-grey"
93
- >
94
- <td class="left"><q-icon class="q-ml-xl q-pl-xl" size="xs" name="insert_drive_file" /></td>
95
- <td class="left">{{ row.market }}</td>
96
- <td>{{ row.product_code }}</td>
97
- <td class="left">
98
- <span style="width: 65px; display: inline-block" class="q-mr-sm">
99
- <q-badge
100
- outline
101
- rounded
102
- :color="stateColor[row.state]"
103
- :label="row.state"
104
- />
105
- </span>
106
- <span>{{ row.product_name }}</span>
107
- </td>
108
- <td>{{ row.sale_period }}</td>
109
- <td class="center">{{ row.stock }}</td>
110
- </tr>
111
- </template>
112
- </q-table>
113
- </template>
114
-
115
- <script>
116
- import { ref, onBeforeMount, watch } from 'vue';
117
-
118
- const stateColor = {
119
- 판매중: 'green',
120
- 판매중지: 'grey',
121
- 품절: 'red',
122
- };
123
-
124
- export default {
125
- name: 'STableTree',
126
- props: {
127
- rows: Array,
128
- columns: Array,
129
- },
130
- setup(props) {
131
- const selectedItem = ref([]);
132
- const visibleProduct = ref([]);
133
- const visibleOption = ref([]);
134
-
135
- const row = ref(props.rows);
136
-
137
- const getSelectedString = ref('');
138
-
139
- onBeforeMount(() => {
140
- row.value.forEach((r) => {
141
- visibleProduct.value[r.id] = true;
142
- visibleOption.value[r.id] = true;
143
- });
144
- });
145
-
146
- watch(
147
- visibleProduct.value,
148
- () => {
149
- const idx = visibleProduct.value.findIndex(i => i === false);
150
- visibleOption.value[idx] = false;
151
- },
152
- );
153
-
154
- function handleVisibleProduct(id) {
155
- visibleProduct.value[id] = !visibleProduct.value[id];
156
- }
157
-
158
- function handleVisibleOption(id) {
159
- visibleOption.value[id] = !visibleOption.value[id];
160
- }
161
- return {
162
- stateColor,
163
- separator: ref('horizontal'),
164
- selectedItem,
165
- visibleProduct,
166
- visibleOption,
167
-
168
- handleVisibleProduct,
169
- handleVisibleOption,
170
-
171
- getSelectedString,
172
-
173
- };
174
- },
175
- };
176
- </script>
177
-
178
- <style scoped lang="sass">
179
- .q-table
180
- thead
181
- tr
182
- height: 32px
183
- th
184
- padding: 0
185
- background: $Grey_Lighten-5
186
- border-bottom: 1px solid #777777
187
- font-weight: 700
188
- font-size: 12px
189
- span
190
- line-height: 32px
191
- tbody
192
- tr
193
- height: 32px !important
194
- td
195
- padding: 0
196
- border-bottom: 1px solid #777777
197
- height: 32px
198
- .background-grey
199
- background: #E5E5E5
200
-
201
- .center
202
- text-align: center !important
203
-
204
- .left
205
- text-align: left !important
206
-
207
- .right
208
- text-align: right !important
209
- </style>