@ozdao/prometheus-framework 0.2.65 → 0.2.66

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdao/prometheus-framework",
3
- "version": "0.2.65",
3
+ "version": "0.2.66",
4
4
  "description": "Web3 Framework focused on user experience and ease of development.",
5
5
  "author": "OZ DAO <hello@ozdao.dev>",
6
6
  "license": "GPL-3.0-or-later",
@@ -2,18 +2,20 @@
2
2
 
3
3
  <TransitionGroup tag="ul" name="scaleTransition" >
4
4
  <BlockSearch
5
- v-if="search"
6
- @search="updateSearch"
7
- placeholder="Enter product name"
8
- class="bg-white mn-b-thin"
9
- />
5
+ v-if="search"
6
+ @search="updateSearch"
7
+ placeholder="Enter product name"
8
+ class="bg-white mn-b-thin"
9
+ />
10
10
  </TransitionGroup>
11
+
11
12
  <TransitionGroup v-if="isLoading" tag="ul" name="scaleTransition" class="o-hidden bg-grey radius-big">
12
13
  <SkeletonEvent
13
14
  v-if="isLoading"
14
15
  v-for="i in currentLimit" :key="i"
15
16
  />
16
17
  </TransitionGroup>
18
+
17
19
  <transition name="scaleTransition">
18
20
  <EmptyState
19
21
  v-if="!isLoading && itemsList.length < 1"
@@ -24,8 +26,6 @@
24
26
  </transition>
25
27
 
26
28
  <TransitionGroup tag="ul" name="scaleTransition" :class="$attrs.class">
27
-
28
-
29
29
  <slot
30
30
  v-if="!isLoading && itemsList.length > 0"
31
31
  :items="itemsList"
@@ -41,7 +41,6 @@
41
41
  </button>
42
42
  </TransitionGroup>
43
43
 
44
-
45
44
  </template>
46
45
 
47
46
  <script setup>
@@ -106,6 +105,14 @@ let isLoading = ref(true);
106
105
  let currentSkip = ref(props.options.skip ? props.options.skip : 0);
107
106
  let currentLimit = ref(props.options.limit ? props.options.limit : 10);
108
107
 
108
+ let currentSearch = ref('');
109
+
110
+ function updateSearch(search) {
111
+ currentSearch.value = search
112
+
113
+ fetchItems();
114
+ }
115
+
109
116
  const loadMoreItems = async () => {
110
117
  if (hasMoreItems.value) {
111
118
  currentSkip.value += currentLimit.value;
@@ -113,6 +120,7 @@ const loadMoreItems = async () => {
113
120
  const data = await props.store.read({
114
121
  skip: currentSkip.value,
115
122
  limit: currentLimit.value,
123
+ search: currentSearch.value,
116
124
  ...props.options
117
125
  });
118
126
 
@@ -132,6 +140,7 @@ const fetchItems = async () => {
132
140
  const data = await props.store.read({
133
141
  skip: currentSkip.value,
134
142
  limit: currentLimit.value,
143
+ search: currentSearch.value,
135
144
  ...props.options
136
145
  });
137
146
 
@@ -143,8 +152,6 @@ const fetchItems = async () => {
143
152
  hasMoreItems.value = true;
144
153
  }
145
154
 
146
- console.log(data)
147
-
148
155
  itemsList.value = data;
149
156
  isLoading.value = false;
150
157
  };
@@ -164,14 +171,6 @@ watch(() => props.options, (newVal, oldVal) => {
164
171
  }
165
172
  }, { deep: true });
166
173
 
167
- function updateSearch(search) {
168
- props.options.search = search
169
-
170
- console.log(search)
171
-
172
- fetchItems();
173
- }
174
-
175
174
 
176
175
  onMounted(async () => {
177
176
  await fetchItems()
@@ -60,6 +60,7 @@
60
60
  @focus="event => emit('focus', event)"
61
61
  @blur="event => emit('blur', event)"
62
62
  class="w-100"
63
+ style="resize: vertical;"
63
64
  :value="field"
64
65
  :placeholder="placeholder"
65
66
  :tabindex="tabindex"
@@ -21,7 +21,7 @@ const visible = ref(false);
21
21
 
22
22
  const tooltipStyle = reactive({
23
23
  position: 'absolute',
24
- 'min-width': '20rem',
24
+ width: 'max-content',
25
25
  zIndex: 1000,
26
26
  background: '#333',
27
27
  color: '#fff',
@@ -35,7 +35,6 @@
35
35
  })"
36
36
  />
37
37
 
38
-
39
38
  <span
40
39
  v-if="type !== 'short'"
41
40
  class="t-semi"
@@ -62,9 +61,13 @@
62
61
  >
63
62
  · by {{creator.target?.profile?.name}}
64
63
  </span>
65
- <span v-if="date">
64
+
65
+ <span v-if="date" class="pos-relative">
66
+ <Tooltip v-if="date" :text="formatDate(date)">
66
67
  · {{getTimeElapsed(date)}}
68
+ </Tooltip>
67
69
  </span>
70
+
68
71
  <span v-if="dateFormatted">
69
72
  · {{dateFormatted}}
70
73
  </span>
@@ -182,7 +185,7 @@
182
185
 
183
186
  import PlaceholderUserpic from '@pf/src/modules/icons/placeholders/PlaceholderUserpic.vue'
184
187
  import FormReport from '@pf/src/modules/reports/components/sections/FormReport.vue'
185
-
188
+ import Tooltip from '@pf/src/components/Tooltip/Tooltip.vue'
186
189
  import Dropdown from "@pf/src/components/Dropdown/Dropdown.vue";
187
190
  import ButtonToggleMembership from '@pf/src/modules/organizations/components/elements/ButtonToggleMembership.vue'
188
191
 
@@ -2,7 +2,7 @@ const ObjectId = require('mongoose').Types.ObjectId;
2
2
 
3
3
  function getBasicOptions(query) {
4
4
  // Деструктуризация для извлечения параметров запроса
5
- const { _id, url, status, owner, creator } = query;
5
+ const { _id, url, status, type, owner, creator } = query;
6
6
 
7
7
  // Подготовка условий для каждого возможного параметра
8
8
  const conditions = [];
@@ -10,6 +10,7 @@ function getBasicOptions(query) {
10
10
  if (_id) { conditions.push({ _id: new ObjectId(_id) }); }
11
11
  if (url) { conditions.push({ url: url }); }
12
12
  if (status) { conditions.push({ status: status }); }
13
+ if (type) { conditions.push({ type: type }); }
13
14
  if (owner) { conditions.push({ "owner.target": new ObjectId(owner) }); }
14
15
  if (creator) { conditions.push({ "creator.target": new ObjectId(creator) }); }
15
16
 
@@ -66,17 +66,16 @@ const actions = {
66
66
  array[existingItemIndex] = item
67
67
  }
68
68
  },
69
-
70
69
  update(array, item) {
71
70
  const existingItemIndex = array.findIndex(i => i._id === item._id);
72
-
73
71
  if (existingItemIndex === -1) {
72
+ // If the item doesn't exist, push it to the array
74
73
  array.push(item);
75
74
  } else {
76
- array[existingItemIndex] = item;
75
+ // Update the item in the array without creating a new array
76
+ Object.assign(array[existingItemIndex], item);
77
77
  }
78
78
  },
79
-
80
79
  delete(array, item) {
81
80
  const existingItemIndex = array.findIndex(c => c._id === item._id);
82
81
 
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div class="flex-column pos-relative flex-wrap">
3
+
3
4
  <CardHeader
4
5
  :entity="leftover"
5
6
  :entityType="'leftover'"
@@ -9,45 +10,64 @@
9
10
  :date="leftover.createdAt"
10
11
  />
11
12
 
12
- <div class="w-100 mn-b-thin flex">
13
- <p class="p-big">
14
- {{leftover.type}}
15
- </p>
13
+ <router-link
14
+ :to="{
15
+ name: 'LeftoverEdit',
16
+ params: {
17
+ _id: leftover.organization,
18
+ leftover: leftover._id
19
+ }
20
+ }"
21
+ class="
22
+ cursor-pointer
23
+ pos-absolute pos-t-regular pos-r-regular
24
+ radius-extra pd-thin bg-second
25
+ "
26
+ >
16
27
  <IconEdit
17
- @click="$router.push({
18
- name: 'LeftoverEdit',
19
- params: {
20
- _id: leftover.organization,
21
- leftover: leftover._id
22
- }
23
- })"
24
- class="pos-absolute pos-t-regular pos-r-regular i-regular t-transp"
28
+ class="i-regular"
29
+ classes="fill-white"
25
30
  />
26
- </div>
27
-
28
-
29
-
30
- <div class="w-100 bg-white radius-small pd-small spoiler">
31
- <div @click="spoiler = !spoiler" class="flex">
32
- <span>Всего товаров {{leftover.positions.length}}</span>
31
+ </router-link>
32
+
33
+ <div class="mn-t-small w-100 bg-white radius-small pd-small spoiler">
34
+ <div @click="spoiler = !spoiler" class="flex-v-center flex">
35
+ <span
36
+ class="flex-child flex-child-shrink-0 capitalize w-max mn-r-thin t-medium radius-big pd-b-nano pd-t-nano pd-r-thin pd-l-thin"
37
+ :class="{
38
+ 'bg-green': leftover.type === 'stock-in',
39
+ 'bg-red': leftover.type === 'stock-out'
40
+ }"
41
+ >
42
+ {{leftover.type}}
43
+ </span>
44
+ <span class="flex-child flex-child-shrink-0">Positions {{leftover.positions.length}}</span>
45
+ <span v-if="leftover.order" class="mn-r-thin mn-l-thin t-transp">|</span>
46
+ <span class="flex-child flex-child-shrink-0" v-if="leftover.order">For order {{leftover.order}}</span>
47
+ <span v-if="leftover.comment" class="mn-r-thin mn-l-thin t-transp">|</span>
48
+ <p v-if="leftover.comment" class="t-truncate">Comment: {{leftover.comment}}</p>
33
49
  <!-- <img :class="{ 'spoiler-active': spoiler }" class="button-icon" src="@/assets/icons/arrow-down-spoiler.svg"> -->
34
50
  </div>
51
+
35
52
  <transition name="fade">
36
53
  <div v-if="spoiler">
37
54
  <div v-for="position in leftover.positions" class="mn-t-small w-100 mn-b-thin flex">
38
55
  <div class=" w-50 flex">
39
56
  <span>
40
- <!-- <span class="t-transp">Название:</span> -->
41
57
  {{position.name}}
42
58
  </span>
59
+ <span class="mn-r-thin mn-l-thin t-transp">|</span>
60
+
61
+ <span class="w-50">
62
+ {{position.price}}
63
+ <span class="t-transp">{{returnCurrency()}}</span>
64
+ </span>
65
+
43
66
  </div>
44
67
 
45
- <div class="t-right w-50 flex">
46
- <span class="w-100">
47
-
48
- {{position.quantity}}
49
- <span class="t-transp">{{declOfNum(position.quantity, ['единица', ' единицы', ' единиц'])}}</span>
50
- </span>
68
+ <div class="t-right w-50">
69
+ {{position.quantity}}
70
+ <span class="t-transp">{{position.type}}</span>
51
71
  </div>
52
72
  </div>
53
73
  </div>
@@ -76,7 +96,7 @@
76
96
  });
77
97
 
78
98
 
79
- const spoiler = ref(false)
99
+ const spoiler = ref(true)
80
100
 
81
101
  function declOfNum(number, words) {
82
102
  return words[(number % 100 > 4 && number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? number % 10 : 5]];
@@ -89,6 +89,19 @@
89
89
  class="mn-b-small radius-medium bg-white pd-small"
90
90
  />
91
91
  </Block>
92
+
93
+ <Block
94
+ title="Comment"
95
+ class="mn-b-semi"
96
+ >
97
+ <Field
98
+ v-model:field="leftovers.state.current.comment"
99
+ label="Comment"
100
+ type="textarea"
101
+ class="w-100 bg-white radius-small pd-medium"
102
+ />
103
+
104
+ </Block>
92
105
 
93
106
  <Block class="">
94
107
  <section class="gap-thin flex-v-center flex-nojustify flex">
@@ -12,7 +12,7 @@
12
12
  </header>
13
13
 
14
14
  <section class="mn-b-semi pd-medium bg-grey radius-big">
15
- <p class="mn-b-thin">Spended:</p>
15
+ <p class="mn-b-thin">Balance:</p>
16
16
  <h3>{{formatPrice(totalPrice)}}</h3>
17
17
  </section>
18
18
 
@@ -47,6 +47,7 @@
47
47
  />
48
48
 
49
49
  <Feed
50
+ :search="true"
50
51
  :states="{
51
52
  empty: {
52
53
  title: 'No Leftovers Found',
@@ -58,9 +59,8 @@
58
59
  }"
59
60
  :options="{
60
61
  limit: 15,
61
- organization: route.params._id,
62
+ owner: route.params._id,
62
63
  ...(tab !== 'all' && { type: tab })
63
- // user: user
64
64
  }"
65
65
  v-slot="{
66
66
  items
@@ -1,29 +1,66 @@
1
+ const queryProcessorGlobals = require('@pf/src/modules/globals/controllers/utils/queryProcessor');
2
+
1
3
  const controllerFactory = (db) => {
2
4
  const Leftover = db.leftover;
3
5
 
4
- const getAll = async (req, res) => {
6
+ const read = async (req, res) => {
5
7
  try {
6
- let query = {};
7
- let options = {};
8
8
 
9
- // Проверка наличия req.query.organization
10
- if (req.query.organization) {
11
- // Создание ObjectId из строки
12
- query.organization = new db.mongoose.Types.ObjectId(req.query.organization);
13
- }
9
+ let matchConditions = [];
10
+
11
+ const search = req.query.search;
12
+
13
+ if (search) {
14
+ const parts = search.split('.');
14
15
 
15
- if (req.query.type) {
16
- query.type = req.query.type;
16
+ let regexPattern = '';
17
+
18
+ if (parts.length === 2) {
19
+ // Создаем паттерн, который допускает замену одного символа в каждой части
20
+ regexPattern = parts.map(part => part.substr(0, part.length - 1) + '.{1}').join('\\.');
21
+ } else {
22
+ // Если нет точки, применяем аналогичный подход к всей строке
23
+ regexPattern = search.substr(0, search.length - 1) + '.{1}';
24
+ }
25
+
26
+ matchConditions.push({
27
+ $or: [
28
+ { "comment": { $regex: regexPattern, $options: 'i' } },
29
+ { "positions.name": { $regex: regexPattern, $options: 'i' } }
30
+ ]
31
+ });
17
32
  }
18
33
 
19
- console.log(query);
34
+ const matchStage = matchConditions.length > 0 ? { $match: { $and: matchConditions } } : null;
35
+
36
+ let stages = [
37
+ ...queryProcessorGlobals.getBasicOptions(
38
+ req.query
39
+ ),
40
+ // For creator
41
+ queryProcessorGlobals.getCreatorUserLookupStage(),
42
+ queryProcessorGlobals.getCreatorOrganizationLookupStage(),
43
+ // For owner
44
+ queryProcessorGlobals.getOwnerUserLookupStage(),
45
+ queryProcessorGlobals.getOwnerOrganizationLookupStage(),
46
+ queryProcessorGlobals.getAddFieldsCreatorOwnerStage(),
47
+
48
+ ...(matchStage != null ? [matchStage] : []),
49
+ // Pagination
50
+ ...queryProcessorGlobals.getSortingOptions(
51
+ req.query.sortParam,
52
+ req.query.sortOrder,
53
+ ),
54
+ ...queryProcessorGlobals.getPaginationOptions(
55
+ req.query.skip,
56
+ req.query.limit
57
+ )
58
+ ];
20
59
 
21
- const leftoveres = await Leftover.find(query, null, options)
22
- .sort({ createdAt: "desc" })
23
- .exec();
60
+ const leftoveres = await Leftover.aggregate(stages).exec();
24
61
 
25
- if (!leftoveres) {
26
- return res.status(404).send({ message: "LEFTOVERES_NOT_FOUND" });
62
+ if (!leftoveres.length) {
63
+ return res.status(404).send({ message: "LEFTOVERES_NOT_FOUND" });
27
64
  }
28
65
 
29
66
  res.status(200).send(leftoveres);
@@ -93,7 +130,7 @@ const controllerFactory = (db) => {
93
130
  };
94
131
 
95
132
  return {
96
- getAll,
133
+ read,
97
134
  create,
98
135
  get,
99
136
  update,
@@ -13,11 +13,16 @@ module.exports = (db) => {
13
13
  required: true,
14
14
  },
15
15
  order: {
16
+ type: db.mongoose.Schema.Types.ObjectId,
17
+ ref: 'Order',
18
+ },
19
+ comment: {
16
20
  type: String
17
21
  },
18
22
  store: {
19
23
  type: Object
20
24
  },
25
+
21
26
  positions: [{
22
27
  _id: {
23
28
  type: db.mongoose.Schema.Types.ObjectId,
@@ -10,7 +10,7 @@ module.exports = function(app, db) {
10
10
 
11
11
  app.get(
12
12
  "/leftovers",
13
- controller.getAll
13
+ controller.read
14
14
  );
15
15
 
16
16
 
@@ -91,8 +91,8 @@
91
91
  // Tones
92
92
  --red: 360, 70, 90;
93
93
  --red-nice: 354, 80, 100;
94
- --green: 120, 58, 70;
95
- --green-nice: 126, 70, 80;
94
+ --green: 88, 207, 57;
95
+ --green-nice: 35, 226, 0;
96
96
  --orange: 8, 72, 94;
97
97
  --orange-nice: 13, 70, 100;
98
98
  --yellow: 38, 100, 100;