Updated via schema editor on 2025-06-19 01:50
This commit is contained in:
parent
6764c421bf
commit
06ef1c22e8
File diff suppressed because one or more lines are too long
@ -15,6 +15,10 @@ module.exports = class OwnersDBApi {
|
|||||||
{
|
{
|
||||||
id: data.id || undefined,
|
id: data.id || undefined,
|
||||||
|
|
||||||
|
lives_on_site: data.lives_on_site || false,
|
||||||
|
|
||||||
|
emergency_contact: data.emergency_contact || null,
|
||||||
|
mailing_address: data.mailing_address || null,
|
||||||
importHash: data.importHash || null,
|
importHash: data.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -22,6 +26,14 @@ module.exports = class OwnersDBApi {
|
|||||||
{ transaction },
|
{ transaction },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await owners.setUser_account(data.user_account || null, {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await owners.setUnit(data.unit || [], {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
return owners;
|
return owners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +45,10 @@ module.exports = class OwnersDBApi {
|
|||||||
const ownersData = data.map((item, index) => ({
|
const ownersData = data.map((item, index) => ({
|
||||||
id: item.id || undefined,
|
id: item.id || undefined,
|
||||||
|
|
||||||
|
lives_on_site: item.lives_on_site || false,
|
||||||
|
|
||||||
|
emergency_contact: item.emergency_contact || null,
|
||||||
|
mailing_address: item.mailing_address || null,
|
||||||
importHash: item.importHash || null,
|
importHash: item.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -55,10 +71,31 @@ module.exports = class OwnersDBApi {
|
|||||||
|
|
||||||
const updatePayload = {};
|
const updatePayload = {};
|
||||||
|
|
||||||
|
if (data.lives_on_site !== undefined)
|
||||||
|
updatePayload.lives_on_site = data.lives_on_site;
|
||||||
|
|
||||||
|
if (data.emergency_contact !== undefined)
|
||||||
|
updatePayload.emergency_contact = data.emergency_contact;
|
||||||
|
|
||||||
|
if (data.mailing_address !== undefined)
|
||||||
|
updatePayload.mailing_address = data.mailing_address;
|
||||||
|
|
||||||
updatePayload.updatedById = currentUser.id;
|
updatePayload.updatedById = currentUser.id;
|
||||||
|
|
||||||
await owners.update(updatePayload, { transaction });
|
await owners.update(updatePayload, { transaction });
|
||||||
|
|
||||||
|
if (data.user_account !== undefined) {
|
||||||
|
await owners.setUser_account(
|
||||||
|
data.user_account,
|
||||||
|
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.unit !== undefined) {
|
||||||
|
await owners.setUnit(data.unit, { transaction });
|
||||||
|
}
|
||||||
|
|
||||||
return owners;
|
return owners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +157,14 @@ module.exports = class OwnersDBApi {
|
|||||||
|
|
||||||
const output = owners.get({ plain: true });
|
const output = owners.get({ plain: true });
|
||||||
|
|
||||||
|
output.user_account = await owners.getUser_account({
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
output.unit = await owners.getUnit({
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +180,39 @@ module.exports = class OwnersDBApi {
|
|||||||
|
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
let include = [];
|
let include = [
|
||||||
|
{
|
||||||
|
model: db.users,
|
||||||
|
as: 'user_account',
|
||||||
|
|
||||||
|
where: filter.user_account
|
||||||
|
? {
|
||||||
|
[Op.or]: [
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
[Op.in]: filter.user_account
|
||||||
|
.split('|')
|
||||||
|
.map((term) => Utils.uuid(term)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstName: {
|
||||||
|
[Op.or]: filter.user_account
|
||||||
|
.split('|')
|
||||||
|
.map((term) => ({ [Op.iLike]: `%${term}%` })),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
model: db.units,
|
||||||
|
as: 'unit',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
if (filter.id) {
|
if (filter.id) {
|
||||||
@ -145,6 +222,28 @@ module.exports = class OwnersDBApi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.emergency_contact) {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
[Op.and]: Utils.ilike(
|
||||||
|
'owners',
|
||||||
|
'emergency_contact',
|
||||||
|
filter.emergency_contact,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.mailing_address) {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
[Op.and]: Utils.ilike(
|
||||||
|
'owners',
|
||||||
|
'mailing_address',
|
||||||
|
filter.mailing_address,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.active !== undefined) {
|
if (filter.active !== undefined) {
|
||||||
where = {
|
where = {
|
||||||
...where,
|
...where,
|
||||||
@ -152,6 +251,45 @@ module.exports = class OwnersDBApi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.lives_on_site) {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
lives_on_site: filter.lives_on_site,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.unit) {
|
||||||
|
const searchTerms = filter.unit.split('|');
|
||||||
|
|
||||||
|
include = [
|
||||||
|
{
|
||||||
|
model: db.units,
|
||||||
|
as: 'unit_filter',
|
||||||
|
required: searchTerms.length > 0,
|
||||||
|
where:
|
||||||
|
searchTerms.length > 0
|
||||||
|
? {
|
||||||
|
[Op.or]: [
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
[Op.in]: searchTerms.map((term) => Utils.uuid(term)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
unit_number: {
|
||||||
|
[Op.or]: searchTerms.map((term) => ({
|
||||||
|
[Op.iLike]: `%${term}%`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
...include,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.createdAtRange) {
|
if (filter.createdAtRange) {
|
||||||
const [start, end] = filter.createdAtRange;
|
const [start, end] = filter.createdAtRange;
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,10 @@ module.exports = class UnitsDBApi {
|
|||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await units.setOwners(data.owners || [], {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
return units;
|
return units;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +98,10 @@ module.exports = class UnitsDBApi {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.owners !== undefined) {
|
||||||
|
await units.setOwners(data.owners, { transaction });
|
||||||
|
}
|
||||||
|
|
||||||
return units;
|
return units;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +177,10 @@ module.exports = class UnitsDBApi {
|
|||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
output.owners = await units.getOwners({
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +222,12 @@ module.exports = class UnitsDBApi {
|
|||||||
}
|
}
|
||||||
: {},
|
: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
model: db.owners,
|
||||||
|
as: 'owners',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
@ -330,6 +348,38 @@ module.exports = class UnitsDBApi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.owners) {
|
||||||
|
const searchTerms = filter.owners.split('|');
|
||||||
|
|
||||||
|
include = [
|
||||||
|
{
|
||||||
|
model: db.owners,
|
||||||
|
as: 'owners_filter',
|
||||||
|
required: searchTerms.length > 0,
|
||||||
|
where:
|
||||||
|
searchTerms.length > 0
|
||||||
|
? {
|
||||||
|
[Op.or]: [
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
[Op.in]: searchTerms.map((term) => Utils.uuid(term)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
[Op.or]: searchTerms.map((term) => ({
|
||||||
|
[Op.iLike]: `%${term}%`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
...include,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.createdAtRange) {
|
if (filter.createdAtRange) {
|
||||||
const [start, end] = filter.createdAtRange;
|
const [start, end] = filter.createdAtRange;
|
||||||
|
|
||||||
|
|||||||
@ -283,6 +283,10 @@ module.exports = class UsersDBApi {
|
|||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
output.owners_user_account = await users.getOwners_user_account({
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
output.avatar = await users.getAvatar({
|
output.avatar = await users.getAvatar({
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|||||||
96
backend/src/db/migrations/1750297828377.js
Normal file
96
backend/src/db/migrations/1750297828377.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* @param {QueryInterface} queryInterface
|
||||||
|
* @param {Sequelize} Sequelize
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
/**
|
||||||
|
* @type {Transaction}
|
||||||
|
*/
|
||||||
|
const transaction = await queryInterface.sequelize.transaction();
|
||||||
|
try {
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'owners',
|
||||||
|
'user_accountId',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.UUID,
|
||||||
|
|
||||||
|
references: {
|
||||||
|
model: 'users',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'owners',
|
||||||
|
'lives_on_site',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.BOOLEAN,
|
||||||
|
|
||||||
|
defaultValue: false,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'owners',
|
||||||
|
'emergency_contact',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.TEXT,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'owners',
|
||||||
|
'mailing_address',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.TEXT,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await transaction.commit();
|
||||||
|
} catch (err) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @param {QueryInterface} queryInterface
|
||||||
|
* @param {Sequelize} Sequelize
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async down(queryInterface, Sequelize) {
|
||||||
|
/**
|
||||||
|
* @type {Transaction}
|
||||||
|
*/
|
||||||
|
const transaction = await queryInterface.sequelize.transaction();
|
||||||
|
try {
|
||||||
|
await queryInterface.removeColumn('owners', 'mailing_address', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('owners', 'emergency_contact', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('owners', 'lives_on_site', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('owners', 'user_accountId', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await transaction.commit();
|
||||||
|
} catch (err) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -14,6 +14,21 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
lives_on_site: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
emergency_contact: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
},
|
||||||
|
|
||||||
|
mailing_address: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
},
|
||||||
|
|
||||||
importHash: {
|
importHash: {
|
||||||
type: DataTypes.STRING(255),
|
type: DataTypes.STRING(255),
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
@ -28,10 +43,36 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
owners.associate = (db) => {
|
owners.associate = (db) => {
|
||||||
|
db.owners.belongsToMany(db.units, {
|
||||||
|
as: 'unit',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'owners_unitId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
through: 'ownersUnitUnits',
|
||||||
|
});
|
||||||
|
|
||||||
|
db.owners.belongsToMany(db.units, {
|
||||||
|
as: 'unit_filter',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'owners_unitId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
through: 'ownersUnitUnits',
|
||||||
|
});
|
||||||
|
|
||||||
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
||||||
|
|
||||||
//end loop
|
//end loop
|
||||||
|
|
||||||
|
db.owners.belongsTo(db.users, {
|
||||||
|
as: 'user_account',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'user_accountId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
|
||||||
db.owners.belongsTo(db.users, {
|
db.owners.belongsTo(db.users, {
|
||||||
as: 'createdBy',
|
as: 'createdBy',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -48,6 +48,24 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
units.associate = (db) => {
|
units.associate = (db) => {
|
||||||
|
db.units.belongsToMany(db.owners, {
|
||||||
|
as: 'owners',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'units_ownersId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
through: 'unitsOwnersOwners',
|
||||||
|
});
|
||||||
|
|
||||||
|
db.units.belongsToMany(db.owners, {
|
||||||
|
as: 'owners_filter',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'units_ownersId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
through: 'unitsOwnersOwners',
|
||||||
|
});
|
||||||
|
|
||||||
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
/// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity
|
||||||
|
|
||||||
db.units.hasMany(db.users, {
|
db.units.hasMany(db.users, {
|
||||||
|
|||||||
@ -110,6 +110,14 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
constraints: false,
|
constraints: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
db.users.hasMany(db.owners, {
|
||||||
|
as: 'owners_user_account',
|
||||||
|
foreignKey: {
|
||||||
|
name: 'user_accountId',
|
||||||
|
},
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
|
||||||
//end loop
|
//end loop
|
||||||
|
|
||||||
db.users.belongsTo(db.roles, {
|
db.users.belongsTo(db.roles, {
|
||||||
|
|||||||
@ -45,6 +45,14 @@ const BudgetsData = [
|
|||||||
|
|
||||||
expenses: 23000,
|
expenses: 23000,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
year: 2019,
|
||||||
|
|
||||||
|
total_budget: 45000,
|
||||||
|
|
||||||
|
expenses: 24000,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const DocumentsData = [
|
const DocumentsData = [
|
||||||
@ -79,6 +87,14 @@ const DocumentsData = [
|
|||||||
|
|
||||||
// type code here for "relation_many" field
|
// type code here for "relation_many" field
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'Maintenance Schedule',
|
||||||
|
|
||||||
|
// type code here for "files" field
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const MaintenanceRequestsData = [
|
const MaintenanceRequestsData = [
|
||||||
@ -87,7 +103,7 @@ const MaintenanceRequestsData = [
|
|||||||
|
|
||||||
description: 'Leaking faucet in kitchen',
|
description: 'Leaking faucet in kitchen',
|
||||||
|
|
||||||
status: 'in_progress',
|
status: 'pending',
|
||||||
|
|
||||||
request_date: new Date('2023-10-01T10:00:00Z'),
|
request_date: new Date('2023-10-01T10:00:00Z'),
|
||||||
},
|
},
|
||||||
@ -97,7 +113,7 @@ const MaintenanceRequestsData = [
|
|||||||
|
|
||||||
description: 'Broken window in living room',
|
description: 'Broken window in living room',
|
||||||
|
|
||||||
status: 'pending',
|
status: 'in_progress',
|
||||||
|
|
||||||
request_date: new Date('2023-09-25T14:30:00Z'),
|
request_date: new Date('2023-09-25T14:30:00Z'),
|
||||||
},
|
},
|
||||||
@ -107,7 +123,7 @@ const MaintenanceRequestsData = [
|
|||||||
|
|
||||||
description: 'Heating not working',
|
description: 'Heating not working',
|
||||||
|
|
||||||
status: 'pending',
|
status: 'in_progress',
|
||||||
|
|
||||||
request_date: new Date('2023-09-20T09:00:00Z'),
|
request_date: new Date('2023-09-20T09:00:00Z'),
|
||||||
},
|
},
|
||||||
@ -117,10 +133,20 @@ const MaintenanceRequestsData = [
|
|||||||
|
|
||||||
description: 'Elevator malfunction',
|
description: 'Elevator malfunction',
|
||||||
|
|
||||||
status: 'pending',
|
status: 'in_progress',
|
||||||
|
|
||||||
request_date: new Date('2023-10-02T11:15:00Z'),
|
request_date: new Date('2023-10-02T11:15:00Z'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
description: 'Paint peeling in hallway',
|
||||||
|
|
||||||
|
status: 'completed',
|
||||||
|
|
||||||
|
request_date: new Date('2023-09-28T13:45:00Z'),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const NoticesData = [
|
const NoticesData = [
|
||||||
@ -163,6 +189,16 @@ const NoticesData = [
|
|||||||
|
|
||||||
sent_date: new Date('2023-09-26T11:00:00Z'),
|
sent_date: new Date('2023-09-26T11:00:00Z'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
|
||||||
|
title: 'Holiday Party',
|
||||||
|
|
||||||
|
content: 'Join us for the holiday party on December 20th.',
|
||||||
|
|
||||||
|
sent_date: new Date('2023-09-25T12:00:00Z'),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const UnitsData = [
|
const UnitsData = [
|
||||||
@ -175,9 +211,11 @@ const UnitsData = [
|
|||||||
|
|
||||||
unit_factor: 1,
|
unit_factor: 1,
|
||||||
|
|
||||||
cond_fee: 52.98,
|
cond_fee: 40.89,
|
||||||
|
|
||||||
parking_stall: 7,
|
parking_stall: 5,
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -187,11 +225,13 @@ const UnitsData = [
|
|||||||
|
|
||||||
balance: 0,
|
balance: 0,
|
||||||
|
|
||||||
unit_factor: 1,
|
unit_factor: 4,
|
||||||
|
|
||||||
cond_fee: 98.25,
|
cond_fee: 27.38,
|
||||||
|
|
||||||
parking_stall: 9,
|
parking_stall: 1,
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -201,11 +241,13 @@ const UnitsData = [
|
|||||||
|
|
||||||
balance: 150,
|
balance: 150,
|
||||||
|
|
||||||
unit_factor: 5,
|
unit_factor: 3,
|
||||||
|
|
||||||
cond_fee: 59.63,
|
cond_fee: 47.22,
|
||||||
|
|
||||||
parking_stall: 8,
|
parking_stall: 9,
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -215,15 +257,93 @@ const UnitsData = [
|
|||||||
|
|
||||||
balance: 0,
|
balance: 0,
|
||||||
|
|
||||||
unit_factor: 7,
|
unit_factor: 8,
|
||||||
|
|
||||||
cond_fee: 32.97,
|
cond_fee: 53.42,
|
||||||
|
|
||||||
parking_stall: 4,
|
parking_stall: 1,
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
unit_number: '105',
|
||||||
|
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
balance: 300,
|
||||||
|
|
||||||
|
unit_factor: 6,
|
||||||
|
|
||||||
|
cond_fee: 18.67,
|
||||||
|
|
||||||
|
parking_stall: 2,
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const OwnersData = [{}, {}, {}, {}];
|
const OwnersData = [
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
lives_on_site: false,
|
||||||
|
|
||||||
|
emergency_contact: 'Leonard Euler',
|
||||||
|
|
||||||
|
mailing_address: 'Jonas Salk',
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
lives_on_site: true,
|
||||||
|
|
||||||
|
emergency_contact: 'Enrico Fermi',
|
||||||
|
|
||||||
|
mailing_address: 'Paul Dirac',
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
lives_on_site: false,
|
||||||
|
|
||||||
|
emergency_contact: 'Claude Bernard',
|
||||||
|
|
||||||
|
mailing_address: 'Frederick Sanger',
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
lives_on_site: true,
|
||||||
|
|
||||||
|
emergency_contact: 'Edward O. Wilson',
|
||||||
|
|
||||||
|
mailing_address: 'J. Robert Oppenheimer',
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
// type code here for "relation_one" field
|
||||||
|
|
||||||
|
lives_on_site: true,
|
||||||
|
|
||||||
|
emergency_contact: 'Joseph J. Thomson',
|
||||||
|
|
||||||
|
mailing_address: 'Michael Faraday',
|
||||||
|
|
||||||
|
// type code here for "relation_many" field
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
// Similar logic for "relation_many"
|
// Similar logic for "relation_many"
|
||||||
|
|
||||||
@ -271,6 +391,17 @@ async function associateUserWithUnit() {
|
|||||||
if (User3?.setUnit) {
|
if (User3?.setUnit) {
|
||||||
await User3.setUnit(relatedUnit3);
|
await User3.setUnit(relatedUnit3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const relatedUnit4 = await Units.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Units.count())),
|
||||||
|
});
|
||||||
|
const User4 = await Users.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 4,
|
||||||
|
});
|
||||||
|
if (User4?.setUnit) {
|
||||||
|
await User4.setUnit(relatedUnit4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar logic for "relation_many"
|
// Similar logic for "relation_many"
|
||||||
@ -319,6 +450,17 @@ async function associateMaintenanceRequestWithUnit() {
|
|||||||
if (MaintenanceRequest3?.setUnit) {
|
if (MaintenanceRequest3?.setUnit) {
|
||||||
await MaintenanceRequest3.setUnit(relatedUnit3);
|
await MaintenanceRequest3.setUnit(relatedUnit3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const relatedUnit4 = await Units.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Units.count())),
|
||||||
|
});
|
||||||
|
const MaintenanceRequest4 = await MaintenanceRequests.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 4,
|
||||||
|
});
|
||||||
|
if (MaintenanceRequest4?.setUnit) {
|
||||||
|
await MaintenanceRequest4.setUnit(relatedUnit4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar logic for "relation_many"
|
// Similar logic for "relation_many"
|
||||||
@ -367,7 +509,79 @@ async function associateUnitWithOwner() {
|
|||||||
if (Unit3?.setOwner) {
|
if (Unit3?.setOwner) {
|
||||||
await Unit3.setOwner(relatedOwner3);
|
await Unit3.setOwner(relatedOwner3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const relatedOwner4 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Unit4 = await Units.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 4,
|
||||||
|
});
|
||||||
|
if (Unit4?.setOwner) {
|
||||||
|
await Unit4.setOwner(relatedOwner4);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Similar logic for "relation_many"
|
||||||
|
|
||||||
|
async function associateOwnerWithUser_account() {
|
||||||
|
const relatedUser_account0 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Owner0 = await Owners.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
if (Owner0?.setUser_account) {
|
||||||
|
await Owner0.setUser_account(relatedUser_account0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedUser_account1 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Owner1 = await Owners.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 1,
|
||||||
|
});
|
||||||
|
if (Owner1?.setUser_account) {
|
||||||
|
await Owner1.setUser_account(relatedUser_account1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedUser_account2 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Owner2 = await Owners.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 2,
|
||||||
|
});
|
||||||
|
if (Owner2?.setUser_account) {
|
||||||
|
await Owner2.setUser_account(relatedUser_account2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedUser_account3 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Owner3 = await Owners.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 3,
|
||||||
|
});
|
||||||
|
if (Owner3?.setUser_account) {
|
||||||
|
await Owner3.setUser_account(relatedUser_account3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedUser_account4 = await Users.findOne({
|
||||||
|
offset: Math.floor(Math.random() * (await Users.count())),
|
||||||
|
});
|
||||||
|
const Owner4 = await Owners.findOne({
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
offset: 4,
|
||||||
|
});
|
||||||
|
if (Owner4?.setUser_account) {
|
||||||
|
await Owner4.setUser_account(relatedUser_account4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Similar logic for "relation_many"
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: async (queryInterface, Sequelize) => {
|
up: async (queryInterface, Sequelize) => {
|
||||||
@ -395,6 +609,12 @@ module.exports = {
|
|||||||
// Similar logic for "relation_many"
|
// Similar logic for "relation_many"
|
||||||
|
|
||||||
await associateUnitWithOwner(),
|
await associateUnitWithOwner(),
|
||||||
|
|
||||||
|
// Similar logic for "relation_many"
|
||||||
|
|
||||||
|
await associateOwnerWithUser_account(),
|
||||||
|
|
||||||
|
// Similar logic for "relation_many"
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,13 @@ router.use(checkCrudPermissions('owners'));
|
|||||||
* type: object
|
* type: object
|
||||||
* properties:
|
* properties:
|
||||||
|
|
||||||
|
* emergency_contact:
|
||||||
|
* type: string
|
||||||
|
* default: emergency_contact
|
||||||
|
* mailing_address:
|
||||||
|
* type: string
|
||||||
|
* default: mailing_address
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +302,7 @@ router.get(
|
|||||||
const currentUser = req.currentUser;
|
const currentUser = req.currentUser;
|
||||||
const payload = await OwnersDBApi.findAll(req.query, { currentUser });
|
const payload = await OwnersDBApi.findAll(req.query, { currentUser });
|
||||||
if (filetype && filetype === 'csv') {
|
if (filetype && filetype === 'csv') {
|
||||||
const fields = ['id'];
|
const fields = ['id', 'emergency_contact', 'mailing_address'];
|
||||||
const opts = { fields };
|
const opts = { fields };
|
||||||
try {
|
try {
|
||||||
const csv = parse(payload.rows, opts);
|
const csv = parse(payload.rows, opts);
|
||||||
|
|||||||
@ -50,6 +50,8 @@ module.exports = class SearchService {
|
|||||||
notices: ['title', 'content'],
|
notices: ['title', 'content'],
|
||||||
|
|
||||||
units: ['unit_number'],
|
units: ['unit_number'],
|
||||||
|
|
||||||
|
owners: ['emergency_contact', 'mailing_address'],
|
||||||
};
|
};
|
||||||
const columnsInt = {
|
const columnsInt = {
|
||||||
budgets: ['year', 'total_budget', 'expenses'],
|
budgets: ['year', 'total_budget', 'expenses'],
|
||||||
|
|||||||
@ -75,7 +75,62 @@ const CardOwners = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<dl className='divide-y divide-stone-300 dark:divide-dark-700 px-6 py-4 text-sm leading-6 h-64 overflow-y-auto'></dl>
|
<dl className='divide-y divide-stone-300 dark:divide-dark-700 px-6 py-4 text-sm leading-6 h-64 overflow-y-auto'>
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
User Account
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{dataFormatter.usersOneListFormatter(item.user_account)}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
Lives On Site
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
Emergency Contact
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{item.emergency_contact}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
Mailing Address
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{item.mailing_address}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>Unit</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{dataFormatter
|
||||||
|
.unitsManyListFormatter(item.unit)
|
||||||
|
.join(', ')}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
{!loading && owners.length === 0 && (
|
{!loading && owners.length === 0 && (
|
||||||
|
|||||||
@ -50,7 +50,46 @@ const ListOwners = ({
|
|||||||
className={
|
className={
|
||||||
'flex-1 px-4 py-6 h-24 flex divide-x-2 divide-stone-300 items-center overflow-hidden`}> dark:divide-dark-700 overflow-x-auto'
|
'flex-1 px-4 py-6 h-24 flex divide-x-2 divide-stone-300 items-center overflow-hidden`}> dark:divide-dark-700 overflow-x-auto'
|
||||||
}
|
}
|
||||||
></Link>
|
>
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>User Account</p>
|
||||||
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter.usersOneListFormatter(item.user_account)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>
|
||||||
|
Lives On Site
|
||||||
|
</p>
|
||||||
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>
|
||||||
|
Emergency Contact
|
||||||
|
</p>
|
||||||
|
<p className={'line-clamp-2'}>{item.emergency_contact}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>
|
||||||
|
Mailing Address
|
||||||
|
</p>
|
||||||
|
<p className={'line-clamp-2'}>{item.mailing_address}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>Unit</p>
|
||||||
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter
|
||||||
|
.unitsManyListFormatter(item.unit)
|
||||||
|
.join(', ')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
<ListActionsPopover
|
<ListActionsPopover
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
itemId={item.id}
|
itemId={item.id}
|
||||||
|
|||||||
@ -20,6 +20,8 @@ import _ from 'lodash';
|
|||||||
import dataFormatter from '../../helpers/dataFormatter';
|
import dataFormatter from '../../helpers/dataFormatter';
|
||||||
import { dataGridStyles } from '../../styles';
|
import { dataGridStyles } from '../../styles';
|
||||||
|
|
||||||
|
import CardOwners from './CardOwners';
|
||||||
|
|
||||||
const perPage = 10;
|
const perPage = 10;
|
||||||
|
|
||||||
const TableSampleOwners = ({
|
const TableSampleOwners = ({
|
||||||
@ -461,7 +463,18 @@ const TableSampleOwners = ({
|
|||||||
<p>Are you sure you want to delete this item?</p>
|
<p>Are you sure you want to delete this item?</p>
|
||||||
</CardBoxModal>
|
</CardBoxModal>
|
||||||
|
|
||||||
{dataGrid}
|
{owners && Array.isArray(owners) && !showGrid && (
|
||||||
|
<CardOwners
|
||||||
|
owners={owners}
|
||||||
|
loading={loading}
|
||||||
|
onDelete={handleDeleteModalAction}
|
||||||
|
currentPage={currentPage}
|
||||||
|
numPages={numPages}
|
||||||
|
onPageChange={onPageChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showGrid && dataGrid}
|
||||||
|
|
||||||
{selectedRows.length > 0 &&
|
{selectedRows.length > 0 &&
|
||||||
createPortal(
|
createPortal(
|
||||||
|
|||||||
@ -38,6 +38,83 @@ export const loadColumns = async (
|
|||||||
const hasUpdatePermission = hasPermission(user, 'UPDATE_OWNERS');
|
const hasUpdatePermission = hasPermission(user, 'UPDATE_OWNERS');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
field: 'user_account',
|
||||||
|
headerName: 'User Account',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: hasUpdatePermission,
|
||||||
|
|
||||||
|
sortable: false,
|
||||||
|
type: 'singleSelect',
|
||||||
|
getOptionValue: (value: any) => value?.id,
|
||||||
|
getOptionLabel: (value: any) => value?.label,
|
||||||
|
valueOptions: await callOptionsApi('users'),
|
||||||
|
valueGetter: (params: GridValueGetterParams) =>
|
||||||
|
params?.value?.id ?? params?.value,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'lives_on_site',
|
||||||
|
headerName: 'Lives On Site',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: hasUpdatePermission,
|
||||||
|
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'emergency_contact',
|
||||||
|
headerName: 'Emergency Contact',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: hasUpdatePermission,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'mailing_address',
|
||||||
|
headerName: 'Mailing Address',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: hasUpdatePermission,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'unit',
|
||||||
|
headerName: 'Unit',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: false,
|
||||||
|
sortable: false,
|
||||||
|
type: 'singleSelect',
|
||||||
|
valueFormatter: ({ value }) =>
|
||||||
|
dataFormatter.unitsManyListFormatter(value).join(', '),
|
||||||
|
renderEditCell: (params) => (
|
||||||
|
<DataGridMultiSelect {...params} entityName={'units'} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
type: 'actions',
|
type: 'actions',
|
||||||
|
|||||||
@ -139,6 +139,19 @@ const CardUnits = ({
|
|||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
Owners
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{dataFormatter
|
||||||
|
.ownersManyListFormatter(item.owners)
|
||||||
|
.join(', ')}
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -84,6 +84,15 @@ const ListUnits = ({
|
|||||||
</p>
|
</p>
|
||||||
<p className={'line-clamp-2'}>{item.parking_stall}</p>
|
<p className={'line-clamp-2'}>{item.parking_stall}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>Owners</p>
|
||||||
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter
|
||||||
|
.ownersManyListFormatter(item.owners)
|
||||||
|
.join(', ')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<ListActionsPopover
|
<ListActionsPopover
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
|||||||
@ -126,6 +126,25 @@ export const loadColumns = async (
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'owners',
|
||||||
|
headerName: 'Owners',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: false,
|
||||||
|
sortable: false,
|
||||||
|
type: 'singleSelect',
|
||||||
|
valueFormatter: ({ value }) =>
|
||||||
|
dataFormatter.ownersManyListFormatter(value).join(', '),
|
||||||
|
renderEditCell: (params) => (
|
||||||
|
<DataGridMultiSelect {...params} entityName={'owners'} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
type: 'actions',
|
type: 'actions',
|
||||||
|
|||||||
@ -114,4 +114,23 @@ export default {
|
|||||||
if (!val) return '';
|
if (!val) return '';
|
||||||
return { label: val.name, id: val.id };
|
return { label: val.name, id: val.id };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ownersManyListFormatter(val) {
|
||||||
|
if (!val || !val.length) return [];
|
||||||
|
return val.map((item) => item.id);
|
||||||
|
},
|
||||||
|
ownersOneListFormatter(val) {
|
||||||
|
if (!val) return '';
|
||||||
|
return val.id;
|
||||||
|
},
|
||||||
|
ownersManyListFormatterEdit(val) {
|
||||||
|
if (!val || !val.length) return [];
|
||||||
|
return val.map((item) => {
|
||||||
|
return { id: item.id, label: item.id };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ownersOneListFormatterEdit(val) {
|
||||||
|
if (!val) return '';
|
||||||
|
return { label: val.id, id: val.id };
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,7 +35,15 @@ import ImageField from '../../components/ImageField';
|
|||||||
const EditOwners = () => {
|
const EditOwners = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const initVals = {};
|
const initVals = {
|
||||||
|
lives_on_site: false,
|
||||||
|
|
||||||
|
emergency_contact: '',
|
||||||
|
|
||||||
|
mailing_address: '',
|
||||||
|
|
||||||
|
unit: [],
|
||||||
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
const { owners } = useAppSelector((state) => state.owners);
|
const { owners } = useAppSelector((state) => state.owners);
|
||||||
@ -87,6 +95,40 @@ const EditOwners = () => {
|
|||||||
onSubmit={(values) => handleSubmit(values)}
|
onSubmit={(values) => handleSubmit(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||||
|
<Field
|
||||||
|
name='lives_on_site'
|
||||||
|
id='lives_on_site'
|
||||||
|
component={SwitchField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Emergency Contact'>
|
||||||
|
<Field
|
||||||
|
name='emergency_contact'
|
||||||
|
placeholder='Emergency Contact'
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Mailing Address' hasTextareaHeight>
|
||||||
|
<Field
|
||||||
|
name='mailing_address'
|
||||||
|
id='mailing_address'
|
||||||
|
component={RichTextField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Unit' labelFor='unit'>
|
||||||
|
<Field
|
||||||
|
name='unit'
|
||||||
|
id='unit'
|
||||||
|
component={SelectFieldMany}
|
||||||
|
options={initialValues.unit}
|
||||||
|
itemRef={'units'}
|
||||||
|
showField={'unit_number'}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -35,7 +35,15 @@ import ImageField from '../../components/ImageField';
|
|||||||
const EditOwnersPage = () => {
|
const EditOwnersPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const initVals = {};
|
const initVals = {
|
||||||
|
lives_on_site: false,
|
||||||
|
|
||||||
|
emergency_contact: '',
|
||||||
|
|
||||||
|
mailing_address: '',
|
||||||
|
|
||||||
|
unit: [],
|
||||||
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
const { owners } = useAppSelector((state) => state.owners);
|
const { owners } = useAppSelector((state) => state.owners);
|
||||||
@ -85,6 +93,40 @@ const EditOwnersPage = () => {
|
|||||||
onSubmit={(values) => handleSubmit(values)}
|
onSubmit={(values) => handleSubmit(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||||
|
<Field
|
||||||
|
name='lives_on_site'
|
||||||
|
id='lives_on_site'
|
||||||
|
component={SwitchField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Emergency Contact'>
|
||||||
|
<Field
|
||||||
|
name='emergency_contact'
|
||||||
|
placeholder='Emergency Contact'
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Mailing Address' hasTextareaHeight>
|
||||||
|
<Field
|
||||||
|
name='mailing_address'
|
||||||
|
id='mailing_address'
|
||||||
|
component={RichTextField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Unit' labelFor='unit'>
|
||||||
|
<Field
|
||||||
|
name='unit'
|
||||||
|
id='unit'
|
||||||
|
component={SelectFieldMany}
|
||||||
|
options={initialValues.unit}
|
||||||
|
itemRef={'units'}
|
||||||
|
showField={'unit_number'}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -28,7 +28,14 @@ const OwnersTablesPage = () => {
|
|||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [filters] = useState([]);
|
const [filters] = useState([
|
||||||
|
{ label: 'Emergency Contact', title: 'emergency_contact' },
|
||||||
|
{ label: 'Mailing Address', title: 'mailing_address' },
|
||||||
|
|
||||||
|
{ label: 'User Account', title: 'user_account' },
|
||||||
|
|
||||||
|
{ label: 'Unit', title: 'unit' },
|
||||||
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
||||||
@ -121,6 +128,10 @@ const OwnersTablesPage = () => {
|
|||||||
<div className='md:inline-flex items-center ms-auto'>
|
<div className='md:inline-flex items-center ms-auto'>
|
||||||
<div id='delete-rows-button'></div>
|
<div id='delete-rows-button'></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='md:inline-flex items-center ms-auto'>
|
||||||
|
<Link href={'/owners/owners-table'}>Switch to Table</Link>
|
||||||
|
</div>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
|
|
||||||
<CardBox className='mb-6' hasTable>
|
<CardBox className='mb-6' hasTable>
|
||||||
|
|||||||
@ -32,7 +32,15 @@ import { useAppDispatch } from '../../stores/hooks';
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
const initialValues = {};
|
const initialValues = {
|
||||||
|
lives_on_site: false,
|
||||||
|
|
||||||
|
emergency_contact: '',
|
||||||
|
|
||||||
|
mailing_address: '',
|
||||||
|
|
||||||
|
unit: [],
|
||||||
|
};
|
||||||
|
|
||||||
const OwnersNew = () => {
|
const OwnersNew = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -61,6 +69,39 @@ const OwnersNew = () => {
|
|||||||
onSubmit={(values) => handleSubmit(values)}
|
onSubmit={(values) => handleSubmit(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
|
<FormField label='Lives On Site' labelFor='lives_on_site'>
|
||||||
|
<Field
|
||||||
|
name='lives_on_site'
|
||||||
|
id='lives_on_site'
|
||||||
|
component={SwitchField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Emergency Contact'>
|
||||||
|
<Field
|
||||||
|
name='emergency_contact'
|
||||||
|
placeholder='Emergency Contact'
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Mailing Address' hasTextareaHeight>
|
||||||
|
<Field
|
||||||
|
name='mailing_address'
|
||||||
|
id='mailing_address'
|
||||||
|
component={RichTextField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Unit' labelFor='unit'>
|
||||||
|
<Field
|
||||||
|
name='unit'
|
||||||
|
id='unit'
|
||||||
|
itemRef={'units'}
|
||||||
|
options={[]}
|
||||||
|
component={SelectFieldMany}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -28,7 +28,14 @@ const OwnersTablesPage = () => {
|
|||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [filters] = useState([]);
|
const [filters] = useState([
|
||||||
|
{ label: 'Emergency Contact', title: 'emergency_contact' },
|
||||||
|
{ label: 'Mailing Address', title: 'mailing_address' },
|
||||||
|
|
||||||
|
{ label: 'User Account', title: 'user_account' },
|
||||||
|
|
||||||
|
{ label: 'Unit', title: 'unit' },
|
||||||
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
currentUser && hasPermission(currentUser, 'CREATE_OWNERS');
|
||||||
@ -120,6 +127,10 @@ const OwnersTablesPage = () => {
|
|||||||
|
|
||||||
<div className='md:inline-flex items-center ms-auto'>
|
<div className='md:inline-flex items-center ms-auto'>
|
||||||
<div id='delete-rows-button'></div>
|
<div id='delete-rows-button'></div>
|
||||||
|
|
||||||
|
<Link href={'/owners/owners-list'}>
|
||||||
|
Back to <span className='capitalize'>card</span>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
<CardBox className='mb-6' hasTable>
|
<CardBox className='mb-6' hasTable>
|
||||||
|
|||||||
@ -54,6 +54,81 @@ const OwnersView = () => {
|
|||||||
/>
|
/>
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
<CardBox>
|
<CardBox>
|
||||||
|
<FormField label='Lives On Site'>
|
||||||
|
<SwitchField
|
||||||
|
field={{ name: 'lives_on_site', value: owners?.lives_on_site }}
|
||||||
|
form={{ setFieldValue: () => null }}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<div className={'mb-4'}>
|
||||||
|
<p className={'block font-bold mb-2'}>Emergency Contact</p>
|
||||||
|
<p>{owners?.emergency_contact}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'mb-4'}>
|
||||||
|
<p className={'block font-bold mb-2'}>Mailing Address</p>
|
||||||
|
{owners.mailing_address ? (
|
||||||
|
<p dangerouslySetInnerHTML={{ __html: owners.mailing_address }} />
|
||||||
|
) : (
|
||||||
|
<p>No data</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<>
|
||||||
|
<p className={'block font-bold mb-2'}>Unit</p>
|
||||||
|
<CardBox
|
||||||
|
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||||
|
hasTable
|
||||||
|
>
|
||||||
|
<div className='overflow-x-auto'>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>UnitNumber</th>
|
||||||
|
|
||||||
|
<th>Balance</th>
|
||||||
|
|
||||||
|
<th>Unit Factor</th>
|
||||||
|
|
||||||
|
<th>Cond Fee</th>
|
||||||
|
|
||||||
|
<th>Parking Stall</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{owners.unit &&
|
||||||
|
Array.isArray(owners.unit) &&
|
||||||
|
owners.unit.map((item: any) => (
|
||||||
|
<tr
|
||||||
|
key={item.id}
|
||||||
|
onClick={() =>
|
||||||
|
router.push(`/units/units-view/?id=${item.id}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<td data-label='unit_number'>{item.unit_number}</td>
|
||||||
|
|
||||||
|
<td data-label='balance'>{item.balance}</td>
|
||||||
|
|
||||||
|
<td data-label='unit_factor'>{item.unit_factor}</td>
|
||||||
|
|
||||||
|
<td data-label='cond_fee'>{item.cond_fee}</td>
|
||||||
|
|
||||||
|
<td data-label='parking_stall'>
|
||||||
|
{item.parking_stall}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{!owners?.unit?.length && (
|
||||||
|
<div className={'text-center py-4'}>No data</div>
|
||||||
|
)}
|
||||||
|
</CardBox>
|
||||||
|
</>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
|
|
||||||
<BaseButton
|
<BaseButton
|
||||||
|
|||||||
@ -47,6 +47,8 @@ const EditUnits = () => {
|
|||||||
cond_fee: '',
|
cond_fee: '',
|
||||||
|
|
||||||
parking_stall: '',
|
parking_stall: '',
|
||||||
|
|
||||||
|
owners: [],
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
@ -138,6 +140,17 @@ const EditUnits = () => {
|
|||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Owners' labelFor='owners'>
|
||||||
|
<Field
|
||||||
|
name='owners'
|
||||||
|
id='owners'
|
||||||
|
component={SelectFieldMany}
|
||||||
|
options={initialValues.owners}
|
||||||
|
itemRef={'owners'}
|
||||||
|
showField={'id'}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -47,6 +47,8 @@ const EditUnitsPage = () => {
|
|||||||
cond_fee: '',
|
cond_fee: '',
|
||||||
|
|
||||||
parking_stall: '',
|
parking_stall: '',
|
||||||
|
|
||||||
|
owners: [],
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
@ -136,6 +138,17 @@ const EditUnitsPage = () => {
|
|||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Owners' labelFor='owners'>
|
||||||
|
<Field
|
||||||
|
name='owners'
|
||||||
|
id='owners'
|
||||||
|
component={SelectFieldMany}
|
||||||
|
options={initialValues.owners}
|
||||||
|
itemRef={'owners'}
|
||||||
|
showField={'id'}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -36,6 +36,8 @@ const UnitsTablesPage = () => {
|
|||||||
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
||||||
|
|
||||||
{ label: 'Owner', title: 'owner' },
|
{ label: 'Owner', title: 'owner' },
|
||||||
|
|
||||||
|
{ label: 'Owners', title: 'owners' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
|
|||||||
@ -44,6 +44,8 @@ const initialValues = {
|
|||||||
cond_fee: '',
|
cond_fee: '',
|
||||||
|
|
||||||
parking_stall: '',
|
parking_stall: '',
|
||||||
|
|
||||||
|
owners: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const UnitsNew = () => {
|
const UnitsNew = () => {
|
||||||
@ -111,6 +113,16 @@ const UnitsNew = () => {
|
|||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Owners' labelFor='owners'>
|
||||||
|
<Field
|
||||||
|
name='owners'
|
||||||
|
id='owners'
|
||||||
|
itemRef={'owners'}
|
||||||
|
options={[]}
|
||||||
|
component={SelectFieldMany}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type='submit' color='info' label='Submit' />
|
<BaseButton type='submit' color='info' label='Submit' />
|
||||||
|
|||||||
@ -36,6 +36,8 @@ const UnitsTablesPage = () => {
|
|||||||
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
{ label: 'Cond Fee', title: 'cond_fee', number: 'true' },
|
||||||
|
|
||||||
{ label: 'Owner', title: 'owner' },
|
{ label: 'Owner', title: 'owner' },
|
||||||
|
|
||||||
|
{ label: 'Owners', title: 'owners' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
|
|||||||
@ -85,6 +85,49 @@ const UnitsView = () => {
|
|||||||
<p>{units?.parking_stall || 'No data'}</p>
|
<p>{units?.parking_stall || 'No data'}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<>
|
||||||
|
<p className={'block font-bold mb-2'}>Owners</p>
|
||||||
|
<CardBox
|
||||||
|
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||||
|
hasTable
|
||||||
|
>
|
||||||
|
<div className='overflow-x-auto'>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Lives On Site</th>
|
||||||
|
|
||||||
|
<th>Emergency Contact</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{units.owners &&
|
||||||
|
Array.isArray(units.owners) &&
|
||||||
|
units.owners.map((item: any) => (
|
||||||
|
<tr
|
||||||
|
key={item.id}
|
||||||
|
onClick={() =>
|
||||||
|
router.push(`/owners/owners-view/?id=${item.id}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<td data-label='lives_on_site'>
|
||||||
|
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-label='emergency_contact'>
|
||||||
|
{item.emergency_contact}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{!units?.owners?.length && (
|
||||||
|
<div className={'text-center py-4'}>No data</div>
|
||||||
|
)}
|
||||||
|
</CardBox>
|
||||||
|
</>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<p className={'block font-bold mb-2'}>Users Unit</p>
|
<p className={'block font-bold mb-2'}>Users Unit</p>
|
||||||
<CardBox
|
<CardBox
|
||||||
|
|||||||
@ -197,6 +197,49 @@ const UsersView = () => {
|
|||||||
</CardBox>
|
</CardBox>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
|
<>
|
||||||
|
<p className={'block font-bold mb-2'}>Owners User Account</p>
|
||||||
|
<CardBox
|
||||||
|
className='mb-6 border border-gray-300 rounded overflow-hidden'
|
||||||
|
hasTable
|
||||||
|
>
|
||||||
|
<div className='overflow-x-auto'>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Lives On Site</th>
|
||||||
|
|
||||||
|
<th>Emergency Contact</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{users.owners_user_account &&
|
||||||
|
Array.isArray(users.owners_user_account) &&
|
||||||
|
users.owners_user_account.map((item: any) => (
|
||||||
|
<tr
|
||||||
|
key={item.id}
|
||||||
|
onClick={() =>
|
||||||
|
router.push(`/owners/owners-view/?id=${item.id}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<td data-label='lives_on_site'>
|
||||||
|
{dataFormatter.booleanFormatter(item.lives_on_site)}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-label='emergency_contact'>
|
||||||
|
{item.emergency_contact}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{!users?.owners_user_account?.length && (
|
||||||
|
<div className={'text-center py-4'}>No data</div>
|
||||||
|
)}
|
||||||
|
</CardBox>
|
||||||
|
</>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
|
|
||||||
<BaseButton
|
<BaseButton
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user