fixed multiple template measurements
This commit is contained in:
parent
08a9a12372
commit
11be1f6f5b
@ -7,7 +7,7 @@ import ChangelogModel from './models/changelog';
|
|||||||
// database urls, prod db url is retrieved automatically
|
// database urls, prod db url is retrieved automatically
|
||||||
const TESTING_URL = 'mongodb://localhost/dfopdb_test';
|
const TESTING_URL = 'mongodb://localhost/dfopdb_test';
|
||||||
const DEV_URL = 'mongodb://localhost/dfopdb';
|
const DEV_URL = 'mongodb://localhost/dfopdb';
|
||||||
const debugging = false;
|
const debugging = true;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production' && debugging) {
|
if (process.env.NODE_ENV !== 'production' && debugging) {
|
||||||
mongoose.set('debug', true); // enable mongoose debug
|
mongoose.set('debug', true); // enable mongoose debug
|
||||||
|
@ -8,7 +8,6 @@ import api from './api';
|
|||||||
import db from './db';
|
import db from './db';
|
||||||
import Mail from './helpers/mail';
|
import Mail from './helpers/mail';
|
||||||
|
|
||||||
// TODO: check header, also in UI
|
|
||||||
|
|
||||||
// tell if server is running in debug or production environment
|
// tell if server is running in debug or production environment
|
||||||
console.info(process.env.NODE_ENV === 'production' ?
|
console.info(process.env.NODE_ENV === 'production' ?
|
||||||
|
@ -22,7 +22,6 @@ router.get('/authorized', (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: evaluate exact changelog functionality (restoring, deleting after time, etc.)
|
|
||||||
router.get('/changelog/:timestamp/:page?/:pagesize?', (req, res, next) => {
|
router.get('/changelog/:timestamp/:page?/:pagesize?', (req, res, next) => {
|
||||||
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
|
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ describe('/sample', () => {
|
|||||||
afterEach(done => TestHelper.afterEach(server, done));
|
afterEach(done => TestHelper.afterEach(server, done));
|
||||||
after(done => TestHelper.after(done));
|
after(done => TestHelper.after(done));
|
||||||
|
|
||||||
// TODO: sort, added date filter, has measurements/condition filter
|
|
||||||
// TODO: check if conditions work in sort/fields/filters
|
|
||||||
// TODO: test for numbers as strings in glass_fiber
|
|
||||||
describe('GET /samples', () => {
|
describe('GET /samples', () => {
|
||||||
it('returns all samples', done => {
|
it('returns all samples', done => {
|
||||||
TestHelper.request(server, done, {
|
TestHelper.request(server, done, {
|
||||||
@ -298,7 +295,7 @@ describe('/sample', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('filters a sample property', done => { // TODO: implement filters
|
it('filters a sample property', done => {
|
||||||
TestHelper.request(server, done, {
|
TestHelper.request(server, done, {
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: '/samples?status[]=new&status[]=validated&fields[]=number&fields[]=type&filters[]=%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22type%22%2C%22values%22%3A%5B%22processed%22%5D%7D',
|
url: '/samples?status[]=new&status[]=validated&fields[]=number&fields[]=type&filters[]=%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22type%22%2C%22values%22%3A%5B%22processed%22%5D%7D',
|
||||||
@ -801,7 +798,7 @@ describe('/sample', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /sample/{id}', () => { // TODO: fix tests, work on /samples
|
describe('PUT /sample/{id}', () => {
|
||||||
it('returns the right sample', done => {
|
it('returns the right sample', done => {
|
||||||
TestHelper.request(server, done, {
|
TestHelper.request(server, done, {
|
||||||
method: 'put',
|
method: 'put',
|
||||||
|
@ -22,13 +22,6 @@ import globals from '../globals';
|
|||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// TODO: check added filter
|
|
||||||
// TODO: convert filter value to number according to table model
|
|
||||||
// TODO: validation for filter parameters
|
|
||||||
// TODO: location/device sort/filter
|
|
||||||
|
|
||||||
// TODO: think about filter keys with measurement template versions
|
|
||||||
|
|
||||||
|
|
||||||
router.get('/samples', async (req, res, next) => {
|
router.get('/samples', async (req, res, next) => {
|
||||||
if (!req.auth(res, ['read', 'write', 'dev', 'admin'], 'all')) return;
|
if (!req.auth(res, ['read', 'write', 'dev', 'admin'], 'all')) return;
|
||||||
@ -40,12 +33,6 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
if ((filters.fields.find(e => e.indexOf('.' + globals.spectrum.dpt) >= 0) || filters.output !== 'json') &&
|
if ((filters.fields.find(e => e.indexOf('.' + globals.spectrum.dpt) >= 0) || filters.output !== 'json') &&
|
||||||
!req.auth(res, ['dev', 'admin'], 'all')) return;
|
!req.auth(res, ['dev', 'admin'], 'all')) return;
|
||||||
|
|
||||||
// TODO: find a better place for these
|
|
||||||
const sampleKeys = ['_id', 'color', 'number', 'type', 'batch', 'added', 'condition', 'material_id', 'note_id',
|
|
||||||
'user_id'];
|
|
||||||
|
|
||||||
// TODO find further optimizations from bachelor thesis
|
|
||||||
|
|
||||||
// evaluate sort parameter from 'color-asc' to ['color', 1]
|
// evaluate sort parameter from 'color-asc' to ['color', 1]
|
||||||
filters.sort = filters.sort.split('-');
|
filters.sort = filters.sort.split('-');
|
||||||
filters.sort[0] = filters.sort[0] === 'added' ? '_id' : filters.sort[0]; // route added sorting criteria to _id
|
filters.sort[0] = filters.sort[0] === 'added' ? '_id' : filters.sort[0]; // route added sorting criteria to _id
|
||||||
@ -123,7 +110,7 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
let sortStartValue = null;
|
let sortStartValue = null;
|
||||||
if (filters['from-id']) { // from-id specified, fetch values for sorting
|
if (filters['from-id']) { // from-id specified, fetch values for sorting
|
||||||
const fromSample = await MeasurementModel.findOne({sample_id: mongoose.Types.ObjectId(filters['from-id'])})
|
const fromSample = await MeasurementModel.findOne({sample_id: mongoose.Types.ObjectId(filters['from-id'])})
|
||||||
.lean().exec().catch(err => {next(err);}); // TODO: what if more than one measurement for sample?
|
.lean().exec().catch(err => {next(err);});
|
||||||
if (fromSample instanceof Error) return;
|
if (fromSample instanceof Error) return;
|
||||||
if (!fromSample) {
|
if (!fromSample) {
|
||||||
return res.status(400).json({status: 'Invalid body format', details: 'from-id not found'});
|
return res.status(400).json({status: 'Invalid body format', details: 'from-id not found'});
|
||||||
@ -149,7 +136,8 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
collection = SampleModel;
|
collection = SampleModel;
|
||||||
queryPtr[0].$match.$and.push(statusQuery(filters, 'status'));
|
queryPtr[0].$match.$and.push(statusQuery(filters, 'status'));
|
||||||
|
|
||||||
if (sampleKeys.indexOf(filters.sort[0]) >= 0) { // sorting for sample keys
|
// sorting for sample keys
|
||||||
|
if (SampleValidate.sampleKeys.indexOf(filters.sort[0]) >= 0 || /condition\./.test(filters.sort[0])) {
|
||||||
let sortStartValue = null;
|
let sortStartValue = null;
|
||||||
if (filters['from-id']) { // from-id specified
|
if (filters['from-id']) { // from-id specified
|
||||||
const fromSample = await SampleModel.findById(filters['from-id']).lean().exec().catch(err => {
|
const fromSample = await SampleModel.findById(filters['from-id']).lean().exec().catch(err => {
|
||||||
@ -168,13 +156,15 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addFilterQueries(queryPtr, filters.filters.filter(e => sampleKeys.indexOf(e.field) >= 0)); // sample filters
|
addFilterQueries(queryPtr, filters.filters.filter(
|
||||||
|
e => (SampleValidate.sampleKeys.indexOf(e.field) >= 0) || /condition\./.test(e.field))
|
||||||
|
); // sample filters
|
||||||
|
|
||||||
let materialQuery = []; // put material query together separate first to reuse for first-id
|
let materialQuery = []; // put material query together separate first to reuse for first-id
|
||||||
let materialAdded = false;
|
let materialAdded = false;
|
||||||
if (sortFilterKeys.find(e => /material\./.test(e))) { // add material fields
|
if (sortFilterKeys.find(e => /material\./.test(e))) { // add material fields
|
||||||
materialAdded = true;
|
materialAdded = true;
|
||||||
materialQuery.push( // add material properties // TODO: project out unnecessary fields
|
materialQuery.push( // add material properties
|
||||||
{$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}},
|
{$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}},
|
||||||
{$addFields: {material: {$arrayElemAt: ['$material', 0]}}}
|
{$addFields: {material: {$arrayElemAt: ['$material', 0]}}}
|
||||||
);
|
);
|
||||||
@ -198,16 +188,8 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
{$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
|
{$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: adapt code to new numbers format
|
|
||||||
// if (sortFilterKeys.find(e => e === 'material.number')) { // add material number if needed
|
|
||||||
// materialQuery.push(
|
|
||||||
// {$addFields: {'material.number': { $arrayElemAt: [
|
|
||||||
// '$material.numbers.number', {$indexOfArray: ['$material.numbers.color', '$color']}
|
|
||||||
// ]}}}
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
const specialMFilters = sortFilterKeys.filter(e => /material\./.test(e))
|
const specialMFilters = sortFilterKeys.filter(e => /material\./.test(e))
|
||||||
.filter(e => ['material.supplier', 'material.group', 'material.number'].indexOf(e) >= 0); // TODO
|
.filter(e => ['material.supplier', 'material.group', 'material.number'].indexOf(e) >= 0);
|
||||||
// base material filters
|
// base material filters
|
||||||
addFilterQueries(materialQuery, filters.filters.filter(e => specialMFilters.indexOf(e.field) >= 0));
|
addFilterQueries(materialQuery, filters.filters.filter(e => specialMFilters.indexOf(e.field) >= 0));
|
||||||
queryPtr.push(...materialQuery);
|
queryPtr.push(...materialQuery);
|
||||||
@ -250,8 +232,17 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
]}}}],
|
]}}}],
|
||||||
as: 'measurements'
|
as: 'measurements'
|
||||||
}});
|
}});
|
||||||
measurementTemplates.forEach(template => {
|
const groupedMeasurementTemplates = measurementTemplates.reduce((s, e) => {
|
||||||
addMeasurements(queryPtr, template);
|
if (s.hasOwnProperty(e.name)) {
|
||||||
|
s[e.name].push(e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s[e.name] = [e];
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}, {});
|
||||||
|
Object.values(groupedMeasurementTemplates).forEach(templates => {
|
||||||
|
addMeasurements(queryPtr, templates);
|
||||||
});
|
});
|
||||||
addFilterQueries(queryPtr, filters.filters
|
addFilterQueries(queryPtr, filters.filters
|
||||||
.filter(e => sortFilterKeys.filter(e => /measurements\./.test(e)).indexOf(e.field) >= 0)
|
.filter(e => sortFilterKeys.filter(e => /measurements\./.test(e)).indexOf(e.field) >= 0)
|
||||||
@ -310,13 +301,6 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
{$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
|
{$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// if (fieldsToAdd.indexOf('material.number') >= 0) { // add material number if needed // TODO
|
|
||||||
// queryPtr.push(
|
|
||||||
// {$addFields: {'material.number': {
|
|
||||||
// $arrayElemAt: ['$material.numbers.number', {$indexOfArray: ['$material.numbers.color', '$color']}]
|
|
||||||
// }}}
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
let measurementFieldsFields: string[] = _.uniq(
|
let measurementFieldsFields: string[] = _.uniq(
|
||||||
fieldsToAdd.filter(e => /measurements\./.test(e)).map(e => e.split('.')[1])
|
fieldsToAdd.filter(e => /measurements\./.test(e)).map(e => e.split('.')[1])
|
||||||
@ -328,8 +312,8 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
if (measurementTemplates.length < measurementFieldsFields.length) {
|
if (measurementTemplates.length < measurementFieldsFields.length) {
|
||||||
return res.status(400).json({status: 'Invalid body format', details: 'Measurement key not found'});
|
return res.status(400).json({status: 'Invalid body format', details: 'Measurement key not found'});
|
||||||
}
|
}
|
||||||
// use different lookup methods with and without spectrum for the best performance
|
// use different lookup methods with and without dpt for the best performance
|
||||||
if (fieldsToAdd.find(e => e.indexOf(globals.spectrum.spectrum + '.') >= 0)) {
|
if (fieldsToAdd.find(e => e.indexOf(globals.spectrum.spectrum + '.' + globals.spectrum.dpt) >= 0)) { // with dpt
|
||||||
queryPtr.push(
|
queryPtr.push(
|
||||||
{$lookup: {from: 'measurements', localField: '_id', foreignField: 'sample_id', as: 'measurements'}}
|
{$lookup: {from: 'measurements', localField: '_id', foreignField: 'sample_id', as: 'measurements'}}
|
||||||
);
|
);
|
||||||
@ -344,21 +328,23 @@ router.get('/samples', async (req, res, next) => {
|
|||||||
as: 'measurements'
|
as: 'measurements'
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
measurementTemplates.forEach(template => {
|
const groupedMeasurementTemplates = measurementTemplates.reduce((s, e) => {
|
||||||
addMeasurements(queryPtr, template);
|
if (s.hasOwnProperty(e.name)) {
|
||||||
if (measurementFieldsFields.find(e => e === globals.spectrum.spectrum)) {
|
s[e.name].push(e);
|
||||||
queryPtr.push({$unwind: '$' + globals.spectrum.spectrum});
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
s[e.name] = [e];
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}, {});
|
||||||
|
Object.values(groupedMeasurementTemplates).forEach(templates => {
|
||||||
|
addMeasurements(queryPtr, templates);
|
||||||
});
|
});
|
||||||
queryPtr.push({$project: {measurements: 0}});
|
queryPtr.push({$project: {measurements: 0}});
|
||||||
}
|
}
|
||||||
|
|
||||||
const projection = filters.fields.map(e => e.replace('measurements.', ''))
|
const projection = filters.fields.map(e => e.replace('measurements.', ''))
|
||||||
.reduce((s, e) => {s[e] = true; return s; }, {});
|
.reduce((s, e) => {s[e] = true; return s; }, {});
|
||||||
if (filters.fields.indexOf('added') >= 0) { // add added date // TODO: upgrade MongoDB version or find alternative
|
|
||||||
// projection.added = {$toDate: '$_id'};
|
|
||||||
// projection.added = { $convert: { input: '$_id', to: "date" } }
|
|
||||||
}
|
|
||||||
if (filters.fields.indexOf('_id') < 0 && filters.fields.indexOf('added') < 0) { // disable _id explicitly
|
if (filters.fields.indexOf('_id') < 0 && filters.fields.indexOf('added') < 0) { // disable _id explicitly
|
||||||
projection._id = false;
|
projection._id = false;
|
||||||
}
|
}
|
||||||
@ -781,12 +767,13 @@ function customFieldsChange (fields, amount, req) { // update custom_fields and
|
|||||||
|
|
||||||
function sortQuery(filters, sortKeys, sortStartValue) { // sortKeys = ['primary key', 'secondary key']
|
function sortQuery(filters, sortKeys, sortStartValue) { // sortKeys = ['primary key', 'secondary key']
|
||||||
if (filters['from-id']) { // from-id specified
|
if (filters['from-id']) { // from-id specified
|
||||||
|
const ssv = sortStartValue !== undefined; // if value is not given, match for existence
|
||||||
if ((filters['to-page'] === 0 && filters.sort[1] === 1) || (filters.sort[1] * filters['to-page'] > 0)) { // asc
|
if ((filters['to-page'] === 0 && filters.sort[1] === 1) || (filters.sort[1] * filters['to-page'] > 0)) { // asc
|
||||||
return [
|
return [
|
||||||
{$match: {$or: [
|
{$match: {$or: [
|
||||||
{[sortKeys[0]]: {$gt: sortStartValue}},
|
{[sortKeys[0]]: ssv ? {$gt: sortStartValue} : {$exists: true}},
|
||||||
{$and: [
|
{$and: [
|
||||||
{[sortKeys[0]]: sortStartValue},
|
{[sortKeys[0]]: ssv ? sortStartValue : {$exists: false}},
|
||||||
{[sortKeys[1]]: {$gte: new mongoose.Types.ObjectId(filters['from-id'])}}
|
{[sortKeys[1]]: {$gte: new mongoose.Types.ObjectId(filters['from-id'])}}
|
||||||
]}
|
]}
|
||||||
]}},
|
]}},
|
||||||
@ -795,9 +782,9 @@ function sortQuery(filters, sortKeys, sortStartValue) { // sortKeys = ['primary
|
|||||||
} else {
|
} else {
|
||||||
return [
|
return [
|
||||||
{$match: {$or: [
|
{$match: {$or: [
|
||||||
{[sortKeys[0]]: {$lt: sortStartValue}},
|
{[sortKeys[0]]: ssv ? {$lt: sortStartValue} : {$exists: false}},
|
||||||
{$and: [
|
{$and: [
|
||||||
{[sortKeys[0]]: sortStartValue},
|
{[sortKeys[0]]: ssv ? sortStartValue : {$exists: true}},
|
||||||
{[sortKeys[1]]: {$lte: new mongoose.Types.ObjectId(filters['from-id'])}}
|
{[sortKeys[1]]: {$lte: new mongoose.Types.ObjectId(filters['from-id'])}}
|
||||||
]}
|
]}
|
||||||
]}},
|
]}},
|
||||||
@ -834,20 +821,25 @@ function filterQueries (filters) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// add measurements as property [template.name], if one result, array is reduced to direct values
|
// add measurements as property [template.name], if one result, array is reduced to direct values. All given templates
|
||||||
function addMeasurements(queryPtr, template) {
|
// must have the same name
|
||||||
|
function addMeasurements(queryPtr, templates) {
|
||||||
queryPtr.push(
|
queryPtr.push(
|
||||||
{$addFields: {[template.name]: {$let: {vars: {
|
{$addFields: {[templates[0].name]: {$let: {vars: {
|
||||||
arr: {$filter: {
|
arr: {$filter: {
|
||||||
input: '$measurements', cond: {$eq: ['$$this.measurement_template', mongoose.Types.ObjectId(template._id)]}
|
input: '$measurements', cond: {$in: [
|
||||||
|
'$$this.measurement_template',
|
||||||
|
templates.map(e => mongoose.Types.ObjectId(e._id))
|
||||||
|
]}
|
||||||
}}},
|
}}},
|
||||||
in: {$cond: [{$lte: [{$size: '$$arr'}, 1]}, {$arrayElemAt: ['$$arr', 0]}, '$$arr']}
|
in: {$cond: [{$lte: [{$size: '$$arr'}, 1]}, {$arrayElemAt: ['$$arr', 0]}, '$$arr']}
|
||||||
}}}},
|
}}}},
|
||||||
{$addFields: {[template.name]: {$cond: [
|
{$addFields: {[templates[0].name]: {$cond: [
|
||||||
'$' + template.name + '.values',
|
'$' + templates[0].name + '.values',
|
||||||
'$' + template.name + '.values',
|
'$' + templates[0].name + '.values',
|
||||||
template.parameters.reduce((s, e) => {s[e.name] = null; return s;}, {})
|
templates[0].parameters.reduce((s, e) => {s[e.name] = null; return s;}, {})
|
||||||
]}}}
|
]}}},
|
||||||
|
{$unwind: '$' + templates[0].name}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import TemplateConditionModel from '../models/condition_template';
|
|||||||
import TemplateMeasurementModel from '../models/measurement_template';
|
import TemplateMeasurementModel from '../models/measurement_template';
|
||||||
import TestHelper from "../test/helper";
|
import TestHelper from "../test/helper";
|
||||||
|
|
||||||
// TODO: method to return only latest template versions -> rework frontend accordingly
|
|
||||||
|
|
||||||
describe('/template', () => {
|
describe('/template', () => {
|
||||||
let server;
|
let server;
|
||||||
|
@ -81,7 +81,6 @@ router.put('/user:username([/](?!key|new).?*|/?)', async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: only possible if no data is linked to user, otherwise change status, etc.
|
|
||||||
// this path matches /user, /user/ and /user/xxx, but not /user/key or user/new.
|
// this path matches /user, /user/ and /user/xxx, but not /user/key or user/new.
|
||||||
// See https://forbeslindesay.github.io/express-route-tester/ for the generated regex
|
// See https://forbeslindesay.github.io/express-route-tester/ for the generated regex
|
||||||
router.delete('/user:username([/](?!key|new).?*|/?)', (req, res, next) => {
|
router.delete('/user:username([/](?!key|new).?*|/?)', (req, res, next) => {
|
||||||
|
@ -6,6 +6,7 @@ import MaterialValidate from './material';
|
|||||||
import MeasurementValidate from './measurement';
|
import MeasurementValidate from './measurement';
|
||||||
import globals from '../../globals';
|
import globals from '../../globals';
|
||||||
|
|
||||||
|
|
||||||
export default class SampleValidate {
|
export default class SampleValidate {
|
||||||
private static sample = {
|
private static sample = {
|
||||||
number: Joi.string()
|
number: Joi.string()
|
||||||
@ -56,6 +57,19 @@ export default class SampleValidate {
|
|||||||
.valid(...Object.values(globals.status))
|
.valid(...Object.values(globals.status))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static readonly sampleKeys = [ // keys which can be found in the sample directly
|
||||||
|
'_id',
|
||||||
|
'color',
|
||||||
|
'number',
|
||||||
|
'type',
|
||||||
|
'batch',
|
||||||
|
'added',
|
||||||
|
'condition',
|
||||||
|
'material_id',
|
||||||
|
'note_id',
|
||||||
|
'user_id'
|
||||||
|
];
|
||||||
|
|
||||||
private static sortKeys = [
|
private static sortKeys = [
|
||||||
'_id',
|
'_id',
|
||||||
'color',
|
'color',
|
||||||
@ -68,6 +82,7 @@ export default class SampleValidate {
|
|||||||
'material.supplier',
|
'material.supplier',
|
||||||
'material.group',
|
'material.group',
|
||||||
'material.properties.*',
|
'material.properties.*',
|
||||||
|
'condition.*',
|
||||||
`measurements.(?!${globals.spectrum.spectrum}.${globals.spectrum.dpt})*`
|
`measurements.(?!${globals.spectrum.spectrum}.${globals.spectrum.dpt})*`
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -189,7 +204,7 @@ export default class SampleValidate {
|
|||||||
});
|
});
|
||||||
field = field.replace('material.', '').split('.')[0];
|
field = field.replace('material.', '').split('.')[0];
|
||||||
}
|
}
|
||||||
else if (/measurements\./.test(field)) {
|
else if (/measurements\./.test(field) || /condition\./.test(field)) {
|
||||||
validator = Joi.object({
|
validator = Joi.object({
|
||||||
value: Joi.alternatives()
|
value: Joi.alternatives()
|
||||||
.try(
|
.try(
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
import IdValidate from './id';
|
import IdValidate from './id';
|
||||||
|
|
||||||
// TODO: do not allow a . in the name !!!
|
|
||||||
export default class TemplateValidate {
|
export default class TemplateValidate {
|
||||||
private static template = {
|
private static template = {
|
||||||
name: Joi.string()
|
name: Joi.string()
|
||||||
|
Reference in New Issue
Block a user