39948-vm/backend/src/db/api/page_elements.js
2026-03-19 07:12:29 +04:00

211 lines
5.6 KiB
JavaScript

const GenericDBApi = require('./base.api');
const db = require('../models');
const Utils = require('../utils');
const {
getRuntimeEnvironment,
getRuntimeProjectSlug,
} = require('./runtime-context');
const Sequelize = db.Sequelize;
const Op = Sequelize.Op;
class Page_elementsDBApi extends GenericDBApi {
static get MODEL() {
return db.page_elements;
}
static get TABLE_NAME() {
return 'page_elements';
}
static get SEARCHABLE_FIELDS() {
return ['name', 'style_json', 'content_json'];
}
static get RANGE_FIELDS() {
return ['sort_order', 'x_percent', 'y_percent', 'width_percent', 'height_percent', 'rotation_deg'];
}
static get ENUM_FIELDS() {
return ['element_type', 'is_visible'];
}
static get CSV_FIELDS() {
return ['id', 'element_type', 'name', 'sort_order', 'is_visible', 'x_percent', 'y_percent', 'createdAt'];
}
static get AUTOCOMPLETE_FIELD() {
return 'name';
}
static get ASSOCIATIONS() {
return [
{ field: 'page', setter: 'setPage', isArray: false },
];
}
static getFieldMapping(data) {
return {
id: data.id || undefined,
element_type: data.element_type ?? null,
name: data.name ?? null,
sort_order: data.sort_order ?? 0,
is_visible: data.is_visible ?? false,
x_percent: data.x_percent ?? null,
y_percent: data.y_percent ?? null,
width_percent: data.width_percent ?? null,
height_percent: data.height_percent ?? null,
rotation_deg: data.rotation_deg ?? null,
style_json: data.style_json ?? null,
content_json: data.content_json ?? null,
};
}
static async findBy(where, options = {}) {
const transaction = options.transaction;
const runtimeEnvironment = getRuntimeEnvironment(options);
const runtimeProjectSlug = getRuntimeProjectSlug(options);
const pageInclude = {
model: db.tour_pages,
as: 'page',
required: Boolean(runtimeEnvironment || runtimeProjectSlug),
where: runtimeEnvironment ? { environment: runtimeEnvironment } : {},
include: runtimeProjectSlug
? [{
model: db.projects,
as: 'project',
required: true,
where: { slug: runtimeProjectSlug },
}]
: [],
};
const record = await this.MODEL.findOne({
where,
transaction,
include: [pageInclude],
});
if (!record) return null;
return record.get({ plain: true });
}
static async findAll(filter = {}, options = {}) {
filter = filter || {};
const limit = filter.limit || 0;
const currentPage = +filter.page || 0;
const offset = currentPage * limit;
let where = {};
let include = [
{
model: db.tour_pages,
as: 'page',
where: filter.page ? {
[Op.or]: [
{ id: { [Op.in]: filter.page.split('|').map(term => Utils.uuid(term)) } },
{
name: {
[Op.or]: filter.page.split('|').map(term => ({ [Op.iLike]: `%${term}%` }))
}
},
]
} : {},
},
];
const runtimeEnvironment = getRuntimeEnvironment(options);
const runtimeProjectSlug = getRuntimeProjectSlug(options);
if (runtimeEnvironment) {
include[0].where = {
...(include[0].where || {}),
environment: runtimeEnvironment,
};
include[0].required = true;
}
if (runtimeProjectSlug) {
include[0].include = [{
model: db.projects,
as: 'project',
required: true,
where: { slug: runtimeProjectSlug },
}];
include[0].required = true;
}
if (filter.id) {
where.id = Utils.uuid(filter.id);
}
for (const field of this.SEARCHABLE_FIELDS) {
if (filter[field]) {
where[Op.and] = Utils.ilike(this.TABLE_NAME, field, filter[field]);
}
}
for (const field of this.RANGE_FIELDS) {
const rangeKey = `${field}Range`;
if (filter[rangeKey]) {
const [start, end] = filter[rangeKey];
if (start !== undefined && start !== null && start !== '') {
where[field] = { ...where[field], [Op.gte]: start };
}
if (end !== undefined && end !== null && end !== '') {
where[field] = { ...where[field], [Op.lte]: end };
}
}
}
for (const field of this.ENUM_FIELDS) {
if (filter[field] !== undefined) {
where[field] = filter[field];
}
}
if (filter.active !== undefined) {
where.active = filter.active === true || filter.active === 'true';
}
if (filter.createdAtRange) {
const [start, end] = filter.createdAtRange;
if (start !== undefined && start !== null && start !== '') {
where.createdAt = { ...where.createdAt, [Op.gte]: start };
}
if (end !== undefined && end !== null && end !== '') {
where.createdAt = { ...where.createdAt, [Op.lte]: end };
}
}
const queryOptions = {
where,
include,
distinct: true,
order: filter.field && filter.sort
? [[filter.field, filter.sort]]
: [['createdAt', 'desc']],
transaction: options.transaction,
};
if (!options.countOnly) {
queryOptions.limit = limit ? Number(limit) : undefined;
queryOptions.offset = offset ? Number(offset) : undefined;
}
try {
const { rows, count } = await this.MODEL.findAndCountAll(queryOptions);
return {
rows: options.countOnly ? [] : rows,
count,
};
} catch (error) {
console.error('Error executing query:', error);
throw error;
}
}
}
module.exports = Page_elementsDBApi;