diff --git a/packages/evershop/bin/dev/index.js b/packages/evershop/bin/dev/index.js index 9733d9f74..1e2291533 100644 --- a/packages/evershop/bin/dev/index.js +++ b/packages/evershop/bin/dev/index.js @@ -2,7 +2,8 @@ process.env.ALLOW_CONFIG_MUTATIONS = true; require('dotenv').config(); const { start } = require('@evershop/evershop/bin/lib/startUp'); +const { watchComponents } = require('../lib/watch/watchComponents'); (async () => { - await start(); + await start(watchComponents); })(); diff --git a/packages/evershop/bin/lib/watch/watchComponents.js b/packages/evershop/bin/lib/watch/watchComponents.js index 1bb072625..4f847a1f4 100644 --- a/packages/evershop/bin/lib/watch/watchComponents.js +++ b/packages/evershop/bin/lib/watch/watchComponents.js @@ -1,34 +1,24 @@ const chokidar = require('chokidar'); -const { resolve, sep, normalize } = require('path'); +const touch = require('touch'); +const { resolve } = require('path'); const { CONSTANTS } = require('@evershop/evershop/src/lib/helpers'); -const { Componee } = require('@evershop/evershop/src/lib/componee/Componee'); -const { - createComponents -} = require('@evershop/evershop/bin/lib/createComponents'); -const { getRoutes } = require('@evershop/evershop/src/lib/router/Router'); -const { - isBuildRequired -} = require('@evershop/evershop/src/lib/webpack/isBuildRequired'); function watchComponents() { chokidar - .watch('**/**/pages/*.js', { - ignored: /node_modules[\\/]/, - ignoreInitial: true, - persistent: true - }) - .on('all', (event, path) => { - const modulePath = resolve(CONSTANTS.ROOTPATH, path).split( - normalize('/views/') - )[0]; - Componee.updateModuleComponents({ - name: modulePath.split(sep).reverse()[0], - path: modulePath - }); - const routes = getRoutes(); - createComponents( - routes.filter((r) => isBuildRequired(r)), - true + .watch( + ['./packages/**/*.jsx', './extensions/**/*.jsx', './themes/**/*.jsx'], + { + ignored: /node_modules[\\/]/, + ignoreInitial: true, + persistent: true + } + ) + .on('add', () => { + touch( + resolve( + CONSTANTS.MOLDULESPATH, + '../components/common/react/client/Index.jsx' + ) ); }); } diff --git a/packages/evershop/src/components/admin/catalog/productEdit/variants/VariantModal.jsx b/packages/evershop/src/components/admin/catalog/productEdit/variants/VariantModal.jsx index 29ff36bea..de16eab3f 100644 --- a/packages/evershop/src/components/admin/catalog/productEdit/variants/VariantModal.jsx +++ b/packages/evershop/src/components/admin/catalog/productEdit/variants/VariantModal.jsx @@ -28,13 +28,18 @@ export function VariantModal({
Min Price | +Shipping Cost | +Action | +
---|---|---|
+ |
+
+ |
+ + { + setRows(rows.filter((r) => r.key !== row.key)); + }} + className="text-critical" + > + Delete + + | +
+ { + setRows([ + ...rows, + { + min_price: '', + shipping_cost: '', + key: Math.random().toString(36).substring(7) + } + ]); + }} + > + + Add Line + + | +
Min Weight | +Shipping Cost | +Action | +
---|---|---|
+ |
+
+ |
+ + { + setRows(rows.filter((r) => r.key !== row.key)); + }} + className="text-critical" + > + Delete + + | +
+ { + setRows([ + ...rows, + { + min_price: '', + shipping_cost: '', + key: Math.random().toString(36).substring(7) + } + ]); + }} + > + + Add Line + + | +
+
+
+
+ Thumbnail
+
+ |
+ )
+ },
sortOrder: 5
},
{
component: {
default: () => (
-
---|
-
-
-
- {title}
-
-
-
- |
- );
-}
-
-IsApprovedHeader.propTypes = {
- id: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- currentFilter: PropTypes.shape({
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
- })
-};
-
-IsApprovedHeader.defaultProps = {
- currentFilter: {}
-};
diff --git a/packages/product_review/pages/admin/reviewGrid/index.js b/packages/product_review/pages/admin/reviewGrid/index.js
index 04242b6fb..d1cd661ed 100644
--- a/packages/product_review/pages/admin/reviewGrid/index.js
+++ b/packages/product_review/pages/admin/reviewGrid/index.js
@@ -11,6 +11,5 @@ module.exports = (request, response) => {
title: 'Reviews',
description: 'Reviews'
});
- const { query } = request;
- setContextValue(request, 'filtersFromUrl', buildFilterFromUrl(query));
+ setContextValue(request, 'filtersFromUrl', buildFilterFromUrl(request));
};
diff --git a/packages/product_review/services/ReviewCollection.js b/packages/product_review/services/ReviewCollection.js
index fa8a4ccdc..8c7003cb1 100644
--- a/packages/product_review/services/ReviewCollection.js
+++ b/packages/product_review/services/ReviewCollection.js
@@ -1,106 +1,45 @@
const { camelCase } = require('@evershop/evershop/src/lib/util/camelCase');
const { pool } = require('@evershop/evershop/src/lib/postgres/connection');
+const { getValue } = require('@evershop/evershop/src/lib/util/registry');
class ReviewCollection {
constructor(baseQuery) {
this.baseQuery = baseQuery;
+ this.baseQuery.orderBy('product_review.review_id', 'DESC');
}
- async init(args, { filters = [] }, { user }) {
- if (!user) {
+ async init(filters = [], isAdmin = false) {
+ if (!isAdmin) {
this.baseQuery.andWhere('product_review.approved', '=', 't');
}
const currentFilters = [];
- // Product Name filter
- const productNameFilter = filters.find((f) => f.key === 'product');
- if (productNameFilter) {
- this.baseQuery.andWhere(
- 'product_description.name',
- 'ILIKE',
- `%${productNameFilter.value}%`
- );
- currentFilters.push({
- key: 'product',
- operation: '=',
- value: productNameFilter.value
- });
- }
-
- // Customer Name filter
- const customerNameFilter = filters.find((f) => f.key === 'customer_name');
- if (customerNameFilter) {
- this.baseQuery.andWhere(
- 'product_review.customer_name',
- 'ILIKE',
- `%${customerNameFilter.value}%`
- );
- currentFilters.push({
- key: 'customer_name',
- operation: '=',
- value: customerNameFilter.value
- });
- }
-
- // Status filter
- const statusFilter = filters.find((f) => f.key === 'approved');
- if (statusFilter) {
- this.baseQuery.andWhere(
- 'product_review.approved',
- '=',
- statusFilter.value
- );
- currentFilters.push({
- key: 'approved',
- operation: '=',
- value: statusFilter.value
- });
- }
-
- const sortBy = filters.find((f) => f.key === 'sortBy');
- const sortOrder = filters.find(
- (f) => f.key === 'sortOrder' && ['ASC', 'DESC'].includes(f.value)
- ) || { value: 'ASC' };
+ // Apply the filters
+ const productReviewCollectionFilters = await getValue(
+ 'productReviewCollectionFilters',
+ []
+ );
- if (sortBy && sortBy.value === 'rating') {
- this.baseQuery.orderBy('product_review.rating', sortOrder.value);
- currentFilters.push({
- key: 'sortBy',
- operation: '=',
- value: sortBy.value
- });
- } else {
- this.baseQuery.orderBy('product_review.review_id', 'DESC');
- }
- if (sortOrder.key) {
- currentFilters.push({
- key: 'sortOrder',
- operation: '=',
- value: sortOrder.value
- });
- }
+ productReviewCollectionFilters.forEach((filter) => {
+ const check = filters.find((f) => f.key === filter.key);
+ if (check) {
+ if (filter.operation.includes(check.operation)) {
+ filter.callback(
+ this.baseQuery,
+ check.operation,
+ check.value,
+ currentFilters
+ );
+ }
+ }
+ });
// Clone the main query for getting total right before doing the paging
const totalQuery = this.baseQuery.clone();
totalQuery.select('COUNT(product_review.review_id)', 'total');
totalQuery.removeOrderBy();
- // Paging
- const page = filters.find((f) => f.key === 'page') || { value: 1 };
- const limit = filters.find((f) => f.key === 'limit') || { value: 20 }; // TODO: Get from the config
- currentFilters.push({
- key: 'page',
- operation: '=',
- value: page.value
- });
- currentFilters.push({
- key: 'limit',
- operation: '=',
- value: limit.value
- });
- this.baseQuery.limit(
- (page.value - 1) * parseInt(limit.value, 10),
- parseInt(limit.value, 10)
- );
+ totalQuery.removeLimit();
+
this.currentFilters = currentFilters;
this.totalQuery = totalQuery;
}
diff --git a/packages/product_review/services/registerDefaultReviewCollectionFilters.js b/packages/product_review/services/registerDefaultReviewCollectionFilters.js
new file mode 100644
index 000000000..98da7c45c
--- /dev/null
+++ b/packages/product_review/services/registerDefaultReviewCollectionFilters.js
@@ -0,0 +1,66 @@
+const {
+ OPERATION_MAP
+} = require('@evershop/evershop/src/lib/util/filterOperationMapp');
+const { getValueSync } = require('@evershop/evershop/src/lib/util/registry');
+
+module.exports = async function registerDefaultReviewCollectionFilters() {
+ // List of default supported filters
+ const defaultFilters = [
+ {
+ key: 'keyword',
+ operation: ['eq'],
+ callback: (query, operation, value, currentFilters) => {
+ query
+ .andWhere('product_description.name', 'ILIKE', `%${value}%`)
+ .or('product_review.customer_name', 'ILIKE', `%${value}%`)
+ .or('product_review.comment', 'ILIKE', `%${value}%`);
+ currentFilters.push({
+ key: 'keyword',
+ operation,
+ value
+ });
+ }
+ },
+ {
+ key: 'status',
+ operation: ['eq'],
+ callback: (query, operation, value, currentFilters) => {
+ query.andWhere(
+ 'product_review.status',
+ OPERATION_MAP[operation],
+ value
+ );
+ currentFilters.push({
+ key: 'status',
+ operation,
+ value
+ });
+ }
+ },
+ {
+ key: 'ob',
+ operation: ['eq'],
+ callback: (query, operation, value, currentFilters) => {
+ const productReviewCollectionSortBy = getValueSync(
+ 'productReviewCollectionSortBy',
+ {
+ product: (query) => query.orderBy('product_description.name'),
+ rating: (query) => query.orderBy('product_review.rating'),
+ status: (query) => query.orderBy('product_review.status')
+ }
+ );
+
+ if (productReviewCollectionSortBy[value]) {
+ productReviewCollectionSortBy[value](query, operation);
+ currentFilters.push({
+ key: 'ob',
+ operation,
+ value
+ });
+ }
+ }
+ }
+ ];
+
+ return defaultFilters;
+};
---|