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;