Commit - 20251016-065731411
This commit is contained in:
parent
d4fa5580aa
commit
0a2bfbdca7
File diff suppressed because one or more lines are too long
44
app-shell/src/_schema.json.erb
Normal file
44
app-shell/src/_schema.json.erb
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<%
|
||||||
|
require 'openssl'
|
||||||
|
require 'base64'
|
||||||
|
%>
|
||||||
|
<%
|
||||||
|
minimal_schema = {
|
||||||
|
"entities" => @schema["entities"],
|
||||||
|
"migrations" => @schema["migrations"]
|
||||||
|
}
|
||||||
|
json_string = minimal_schema.to_json.gsub(/"@(\w+)":/, '"\1":')
|
||||||
|
%>
|
||||||
|
<%
|
||||||
|
key_b64 = 'oAYZbSQ7otWLWy/1v6KGwzcpfe4LxdtkDcAUD7HAaw0='
|
||||||
|
raise "SCHEMA_ENCRYPTION_KEY environment variable is not set or empty" if key_b64.nil? || key_b64.empty?
|
||||||
|
|
||||||
|
key = Base64.strict_decode64(key_b64)
|
||||||
|
raise "Invalid key length: expected 32 bytes for AES-256-GCM" unless key.bytesize == 32
|
||||||
|
|
||||||
|
cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
|
||||||
|
cipher.key = key
|
||||||
|
|
||||||
|
iv = cipher.random_iv
|
||||||
|
cipher.iv = iv
|
||||||
|
|
||||||
|
encrypted_data = cipher.update(json_string) + cipher.final
|
||||||
|
auth_tag = cipher.auth_tag
|
||||||
|
|
||||||
|
iv_b64 = Base64.strict_encode64(iv)
|
||||||
|
|
||||||
|
ciphertext_with_tag = encrypted_data + auth_tag
|
||||||
|
ciphertext_b64 = Base64.strict_encode64(ciphertext_with_tag)
|
||||||
|
|
||||||
|
encrypted_payload = {
|
||||||
|
"iv" => iv_b64,
|
||||||
|
"encryptedData" => ciphertext_b64
|
||||||
|
}
|
||||||
|
output_payload_string = encrypted_payload.to_json
|
||||||
|
|
||||||
|
escaped_output_payload_string = output_payload_string.gsub('"', '\\"')
|
||||||
|
%>
|
||||||
|
|
||||||
|
{
|
||||||
|
"Initial version": "<%= escaped_output_payload_string %>"
|
||||||
|
}
|
||||||
@ -1,13 +1,13 @@
|
|||||||
|
<% require 'digest/md5' %>
|
||||||
|
<% @app_admin_password = @schema['project']['@project_uuid'] ? @schema['project']['@project_uuid'].split('-').first : 'password' %>
|
||||||
const config = {
|
const config = {
|
||||||
admin_pass: "df170051",
|
admin_pass: "<%= @app_admin_password %>",
|
||||||
admin_email: "admin@flatlogic.com",
|
admin_email: "admin@flatlogic.com",
|
||||||
schema_encryption_key: process.env.SCHEMA_ENCRYPTION_KEY || '',
|
schema_encryption_key: process.env.SCHEMA_ENCRYPTION_KEY || '',
|
||||||
|
<% if @schema['project']['@project_uuid'] %>
|
||||||
project_uuid: 'df170051-a138-4641-ad0d-a5ac07a19601',
|
project_uuid: '<%= @schema['project']['@project_uuid'] %>',
|
||||||
flHost: process.env.NODE_ENV === 'production' ? 'https://flatlogic.com/projects' : 'http://localhost:3000/projects',
|
flHost: process.env.NODE_ENV === 'production' ? 'https://flatlogic.com/projects' : 'http://localhost:3000/projects',
|
||||||
|
<% end %>
|
||||||
gitea_domain: process.env.GITEA_DOMAIN || 'gitea.flatlogic.app',
|
gitea_domain: process.env.GITEA_DOMAIN || 'gitea.flatlogic.app',
|
||||||
gitea_username: process.env.GITEA_USERNAME || 'admin',
|
gitea_username: process.env.GITEA_USERNAME || 'admin',
|
||||||
gitea_api_token: process.env.GITEA_API_TOKEN || null,
|
gitea_api_token: process.env.GITEA_API_TOKEN || null,
|
||||||
@ -11,7 +11,7 @@ const vcsRoutes = require('./routes/vcs');
|
|||||||
|
|
||||||
// Function to initialize the Git repository
|
// Function to initialize the Git repository
|
||||||
function initRepo() {
|
function initRepo() {
|
||||||
const projectId = '34916';
|
const projectId = '<%= @schema['project']['project_id'] %>';
|
||||||
return VCS.initRepo(projectId);
|
return VCS.initRepo(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +51,4 @@ startServer();
|
|||||||
// Now perform Git check
|
// Now perform Git check
|
||||||
runGitCheck();
|
runGitCheck();
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
@ -19,8 +19,6 @@ module.exports = class Archival_itemsDBApi {
|
|||||||
description: data.description || null,
|
description: data.description || null,
|
||||||
isPublished: data.isPublished || false,
|
isPublished: data.isPublished || false,
|
||||||
|
|
||||||
period_from: data.period_from || null,
|
|
||||||
period_to: data.period_to || null,
|
|
||||||
importHash: data.importHash || null,
|
importHash: data.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -57,8 +55,6 @@ module.exports = class Archival_itemsDBApi {
|
|||||||
description: item.description || null,
|
description: item.description || null,
|
||||||
isPublished: item.isPublished || false,
|
isPublished: item.isPublished || false,
|
||||||
|
|
||||||
period_from: item.period_from || null,
|
|
||||||
period_to: item.period_to || null,
|
|
||||||
importHash: item.importHash || null,
|
importHash: item.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -108,11 +104,6 @@ module.exports = class Archival_itemsDBApi {
|
|||||||
if (data.isPublished !== undefined)
|
if (data.isPublished !== undefined)
|
||||||
updatePayload.isPublished = data.isPublished;
|
updatePayload.isPublished = data.isPublished;
|
||||||
|
|
||||||
if (data.period_from !== undefined)
|
|
||||||
updatePayload.period_from = data.period_from;
|
|
||||||
|
|
||||||
if (data.period_to !== undefined) updatePayload.period_to = data.period_to;
|
|
||||||
|
|
||||||
updatePayload.updatedById = currentUser.id;
|
updatePayload.updatedById = currentUser.id;
|
||||||
|
|
||||||
await archival_items.update(updatePayload, { transaction });
|
await archival_items.update(updatePayload, { transaction });
|
||||||
@ -257,41 +248,6 @@ module.exports = class Archival_itemsDBApi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.period_to) {
|
|
||||||
where = {
|
|
||||||
...where,
|
|
||||||
[Op.and]: Utils.ilike(
|
|
||||||
'archival_items',
|
|
||||||
'period_to',
|
|
||||||
filter.period_to,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.period_fromRange) {
|
|
||||||
const [start, end] = filter.period_fromRange;
|
|
||||||
|
|
||||||
if (start !== undefined && start !== null && start !== '') {
|
|
||||||
where = {
|
|
||||||
...where,
|
|
||||||
period_from: {
|
|
||||||
...where.period_from,
|
|
||||||
[Op.gte]: start,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end !== undefined && end !== null && end !== '') {
|
|
||||||
where = {
|
|
||||||
...where,
|
|
||||||
period_from: {
|
|
||||||
...where.period_from,
|
|
||||||
[Op.lte]: end,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.active !== undefined) {
|
if (filter.active !== undefined) {
|
||||||
where = {
|
where = {
|
||||||
...where,
|
...where,
|
||||||
|
|||||||
@ -6,16 +6,18 @@ const Utils = require('../utils');
|
|||||||
const Sequelize = db.Sequelize;
|
const Sequelize = db.Sequelize;
|
||||||
const Op = Sequelize.Op;
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
module.exports = class GalleriesDBApi {
|
module.exports = class PeriodsDBApi {
|
||||||
static async create(data, options) {
|
static async create(data, options) {
|
||||||
const currentUser = (options && options.currentUser) || { id: null };
|
const currentUser = (options && options.currentUser) || { id: null };
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
const galleries = await db.galleries.create(
|
const periods = await db.periods.create(
|
||||||
{
|
{
|
||||||
id: data.id || undefined,
|
id: data.id || undefined,
|
||||||
|
|
||||||
name: data.name || null,
|
name: data.name || null,
|
||||||
|
period_from: data.period_from || null,
|
||||||
|
period_to: data.period_to || null,
|
||||||
importHash: data.importHash || null,
|
importHash: data.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -23,21 +25,11 @@ module.exports = class GalleriesDBApi {
|
|||||||
{ transaction },
|
{ transaction },
|
||||||
);
|
);
|
||||||
|
|
||||||
await galleries.setArchival_items(data.archival_items || [], {
|
await periods.setArchival_items(data.archival_items || [], {
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
await FileDBApi.replaceRelationFiles(
|
return periods;
|
||||||
{
|
|
||||||
belongsTo: db.galleries.getTableName(),
|
|
||||||
belongsToColumn: 'background_image',
|
|
||||||
belongsToId: galleries.id,
|
|
||||||
},
|
|
||||||
data.background_image,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
|
|
||||||
return galleries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async bulkImport(data, options) {
|
static async bulkImport(data, options) {
|
||||||
@ -45,10 +37,12 @@ module.exports = class GalleriesDBApi {
|
|||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
// Prepare data - wrapping individual data transformations in a map() method
|
// Prepare data - wrapping individual data transformations in a map() method
|
||||||
const galleriesData = data.map((item, index) => ({
|
const periodsData = data.map((item, index) => ({
|
||||||
id: item.id || undefined,
|
id: item.id || undefined,
|
||||||
|
|
||||||
name: item.name || null,
|
name: item.name || null,
|
||||||
|
period_from: item.period_from || null,
|
||||||
|
period_to: item.period_to || null,
|
||||||
importHash: item.importHash || null,
|
importHash: item.importHash || null,
|
||||||
createdById: currentUser.id,
|
createdById: currentUser.id,
|
||||||
updatedById: currentUser.id,
|
updatedById: currentUser.id,
|
||||||
@ -56,63 +50,44 @@ module.exports = class GalleriesDBApi {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Bulk create items
|
// Bulk create items
|
||||||
const galleries = await db.galleries.bulkCreate(galleriesData, {
|
const periods = await db.periods.bulkCreate(periodsData, { transaction });
|
||||||
transaction,
|
|
||||||
});
|
|
||||||
|
|
||||||
// For each item created, replace relation files
|
// For each item created, replace relation files
|
||||||
|
|
||||||
for (let i = 0; i < galleries.length; i++) {
|
return periods;
|
||||||
await FileDBApi.replaceRelationFiles(
|
|
||||||
{
|
|
||||||
belongsTo: db.galleries.getTableName(),
|
|
||||||
belongsToColumn: 'background_image',
|
|
||||||
belongsToId: galleries[i].id,
|
|
||||||
},
|
|
||||||
data[i].background_image,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return galleries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async update(id, data, options) {
|
static async update(id, data, options) {
|
||||||
const currentUser = (options && options.currentUser) || { id: null };
|
const currentUser = (options && options.currentUser) || { id: null };
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
const galleries = await db.galleries.findByPk(id, {}, { transaction });
|
const periods = await db.periods.findByPk(id, {}, { transaction });
|
||||||
|
|
||||||
const updatePayload = {};
|
const updatePayload = {};
|
||||||
|
|
||||||
if (data.name !== undefined) updatePayload.name = data.name;
|
if (data.name !== undefined) updatePayload.name = data.name;
|
||||||
|
|
||||||
|
if (data.period_from !== undefined)
|
||||||
|
updatePayload.period_from = data.period_from;
|
||||||
|
|
||||||
|
if (data.period_to !== undefined) updatePayload.period_to = data.period_to;
|
||||||
|
|
||||||
updatePayload.updatedById = currentUser.id;
|
updatePayload.updatedById = currentUser.id;
|
||||||
|
|
||||||
await galleries.update(updatePayload, { transaction });
|
await periods.update(updatePayload, { transaction });
|
||||||
|
|
||||||
if (data.archival_items !== undefined) {
|
if (data.archival_items !== undefined) {
|
||||||
await galleries.setArchival_items(data.archival_items, { transaction });
|
await periods.setArchival_items(data.archival_items, { transaction });
|
||||||
}
|
}
|
||||||
|
|
||||||
await FileDBApi.replaceRelationFiles(
|
return periods;
|
||||||
{
|
|
||||||
belongsTo: db.galleries.getTableName(),
|
|
||||||
belongsToColumn: 'background_image',
|
|
||||||
belongsToId: galleries.id,
|
|
||||||
},
|
|
||||||
data.background_image,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
|
|
||||||
return galleries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async deleteByIds(ids, options) {
|
static async deleteByIds(ids, options) {
|
||||||
const currentUser = (options && options.currentUser) || { id: null };
|
const currentUser = (options && options.currentUser) || { id: null };
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
const galleries = await db.galleries.findAll({
|
const periods = await db.periods.findAll({
|
||||||
where: {
|
where: {
|
||||||
id: {
|
id: {
|
||||||
[Op.in]: ids,
|
[Op.in]: ids,
|
||||||
@ -122,24 +97,24 @@ module.exports = class GalleriesDBApi {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await db.sequelize.transaction(async (transaction) => {
|
await db.sequelize.transaction(async (transaction) => {
|
||||||
for (const record of galleries) {
|
for (const record of periods) {
|
||||||
await record.update({ deletedBy: currentUser.id }, { transaction });
|
await record.update({ deletedBy: currentUser.id }, { transaction });
|
||||||
}
|
}
|
||||||
for (const record of galleries) {
|
for (const record of periods) {
|
||||||
await record.destroy({ transaction });
|
await record.destroy({ transaction });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return galleries;
|
return periods;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async remove(id, options) {
|
static async remove(id, options) {
|
||||||
const currentUser = (options && options.currentUser) || { id: null };
|
const currentUser = (options && options.currentUser) || { id: null };
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
const galleries = await db.galleries.findByPk(id, options);
|
const periods = await db.periods.findByPk(id, options);
|
||||||
|
|
||||||
await galleries.update(
|
await periods.update(
|
||||||
{
|
{
|
||||||
deletedBy: currentUser.id,
|
deletedBy: currentUser.id,
|
||||||
},
|
},
|
||||||
@ -148,29 +123,25 @@ module.exports = class GalleriesDBApi {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
await galleries.destroy({
|
await periods.destroy({
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
return galleries;
|
return periods;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async findBy(where, options) {
|
static async findBy(where, options) {
|
||||||
const transaction = (options && options.transaction) || undefined;
|
const transaction = (options && options.transaction) || undefined;
|
||||||
|
|
||||||
const galleries = await db.galleries.findOne({ where }, { transaction });
|
const periods = await db.periods.findOne({ where }, { transaction });
|
||||||
|
|
||||||
if (!galleries) {
|
if (!periods) {
|
||||||
return galleries;
|
return periods;
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = galleries.get({ plain: true });
|
const output = periods.get({ plain: true });
|
||||||
|
|
||||||
output.archival_items = await galleries.getArchival_items({
|
output.archival_items = await periods.getArchival_items({
|
||||||
transaction,
|
|
||||||
});
|
|
||||||
|
|
||||||
output.background_image = await galleries.getBackground_image({
|
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -195,11 +166,6 @@ module.exports = class GalleriesDBApi {
|
|||||||
as: 'archival_items',
|
as: 'archival_items',
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
model: db.file,
|
|
||||||
as: 'background_image',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
@ -213,10 +179,58 @@ module.exports = class GalleriesDBApi {
|
|||||||
if (filter.name) {
|
if (filter.name) {
|
||||||
where = {
|
where = {
|
||||||
...where,
|
...where,
|
||||||
[Op.and]: Utils.ilike('galleries', 'name', filter.name),
|
[Op.and]: Utils.ilike('periods', 'name', filter.name),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.period_fromRange) {
|
||||||
|
const [start, end] = filter.period_fromRange;
|
||||||
|
|
||||||
|
if (start !== undefined && start !== null && start !== '') {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
period_from: {
|
||||||
|
...where.period_from,
|
||||||
|
[Op.gte]: start,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end !== undefined && end !== null && end !== '') {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
period_from: {
|
||||||
|
...where.period_from,
|
||||||
|
[Op.lte]: end,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.period_toRange) {
|
||||||
|
const [start, end] = filter.period_toRange;
|
||||||
|
|
||||||
|
if (start !== undefined && start !== null && start !== '') {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
period_to: {
|
||||||
|
...where.period_to,
|
||||||
|
[Op.gte]: start,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end !== undefined && end !== null && end !== '') {
|
||||||
|
where = {
|
||||||
|
...where,
|
||||||
|
period_to: {
|
||||||
|
...where.period_to,
|
||||||
|
[Op.lte]: end,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.active !== undefined) {
|
if (filter.active !== undefined) {
|
||||||
where = {
|
where = {
|
||||||
...where,
|
...where,
|
||||||
@ -299,7 +313,7 @@ module.exports = class GalleriesDBApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { rows, count } = await db.galleries.findAndCountAll(queryOptions);
|
const { rows, count } = await db.periods.findAndCountAll(queryOptions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rows: options?.countOnly ? [] : rows,
|
rows: options?.countOnly ? [] : rows,
|
||||||
@ -318,12 +332,12 @@ module.exports = class GalleriesDBApi {
|
|||||||
where = {
|
where = {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
{ ['id']: Utils.uuid(query) },
|
{ ['id']: Utils.uuid(query) },
|
||||||
Utils.ilike('galleries', 'id', query),
|
Utils.ilike('periods', 'id', query),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const records = await db.galleries.findAll({
|
const records = await db.periods.findAll({
|
||||||
attributes: ['id', 'id'],
|
attributes: ['id', 'id'],
|
||||||
where,
|
where,
|
||||||
limit: limit ? Number(limit) : undefined,
|
limit: limit ? Number(limit) : undefined,
|
||||||
92
backend/src/db/migrations/1760597839174.js
Normal file
92
backend/src/db/migrations/1760597839174.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
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.renameTable('galleries', 'periods', { transaction });
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'periods',
|
||||||
|
'period_from',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'periods',
|
||||||
|
'period_to',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('archival_items', 'period_from', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('archival_items', 'period_to', {
|
||||||
|
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.addColumn(
|
||||||
|
'archival_items',
|
||||||
|
'period_to',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.TEXT,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.addColumn(
|
||||||
|
'archival_items',
|
||||||
|
'period_from',
|
||||||
|
{
|
||||||
|
type: Sequelize.DataTypes.DATEONLY,
|
||||||
|
},
|
||||||
|
{ transaction },
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('periods', 'period_to', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.removeColumn('periods', 'period_from', {
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.renameTable('periods', 'galleries', { transaction });
|
||||||
|
|
||||||
|
await transaction.commit();
|
||||||
|
} catch (err) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -29,20 +29,6 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
period_from: {
|
|
||||||
type: DataTypes.DATEONLY,
|
|
||||||
|
|
||||||
get: function () {
|
|
||||||
return this.getDataValue('period_from')
|
|
||||||
? moment.utc(this.getDataValue('period_from')).format('YYYY-MM-DD')
|
|
||||||
: null;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
period_to: {
|
|
||||||
type: DataTypes.TEXT,
|
|
||||||
},
|
|
||||||
|
|
||||||
importHash: {
|
importHash: {
|
||||||
type: DataTypes.STRING(255),
|
type: DataTypes.STRING(255),
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
|||||||
@ -5,8 +5,8 @@ const bcrypt = require('bcrypt');
|
|||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
|
|
||||||
module.exports = function (sequelize, DataTypes) {
|
module.exports = function (sequelize, DataTypes) {
|
||||||
const galleries = sequelize.define(
|
const periods = sequelize.define(
|
||||||
'galleries',
|
'periods',
|
||||||
{
|
{
|
||||||
id: {
|
id: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
@ -18,6 +18,14 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
type: DataTypes.TEXT,
|
type: DataTypes.TEXT,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
period_from: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
|
||||||
|
period_to: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
|
||||||
importHash: {
|
importHash: {
|
||||||
type: DataTypes.STRING(255),
|
type: DataTypes.STRING(255),
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
@ -31,47 +39,37 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
galleries.associate = (db) => {
|
periods.associate = (db) => {
|
||||||
db.galleries.belongsToMany(db.archival_items, {
|
db.periods.belongsToMany(db.archival_items, {
|
||||||
as: 'archival_items',
|
as: 'archival_items',
|
||||||
foreignKey: {
|
foreignKey: {
|
||||||
name: 'galleries_archival_itemsId',
|
name: 'periods_archival_itemsId',
|
||||||
},
|
},
|
||||||
constraints: false,
|
constraints: false,
|
||||||
through: 'galleriesArchival_itemsArchival_items',
|
through: 'periodsArchival_itemsArchival_items',
|
||||||
});
|
});
|
||||||
|
|
||||||
db.galleries.belongsToMany(db.archival_items, {
|
db.periods.belongsToMany(db.archival_items, {
|
||||||
as: 'archival_items_filter',
|
as: 'archival_items_filter',
|
||||||
foreignKey: {
|
foreignKey: {
|
||||||
name: 'galleries_archival_itemsId',
|
name: 'periods_archival_itemsId',
|
||||||
},
|
},
|
||||||
constraints: false,
|
constraints: false,
|
||||||
through: 'galleriesArchival_itemsArchival_items',
|
through: 'periodsArchival_itemsArchival_items',
|
||||||
});
|
});
|
||||||
|
|
||||||
/// 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.galleries.hasMany(db.file, {
|
db.periods.belongsTo(db.users, {
|
||||||
as: 'background_image',
|
|
||||||
foreignKey: 'belongsToId',
|
|
||||||
constraints: false,
|
|
||||||
scope: {
|
|
||||||
belongsTo: db.galleries.getTableName(),
|
|
||||||
belongsToColumn: 'background_image',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
db.galleries.belongsTo(db.users, {
|
|
||||||
as: 'createdBy',
|
as: 'createdBy',
|
||||||
});
|
});
|
||||||
|
|
||||||
db.galleries.belongsTo(db.users, {
|
db.periods.belongsTo(db.users, {
|
||||||
as: 'updatedBy',
|
as: 'updatedBy',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return galleries;
|
return periods;
|
||||||
};
|
};
|
||||||
@ -72,7 +72,7 @@ module.exports = {
|
|||||||
const entities = [
|
const entities = [
|
||||||
'users',
|
'users',
|
||||||
'archival_items',
|
'archival_items',
|
||||||
'galleries',
|
'periods',
|
||||||
'tags',
|
'tags',
|
||||||
'roles',
|
'roles',
|
||||||
'permissions',
|
'permissions',
|
||||||
@ -164,25 +164,25 @@ primary key ("roles_permissionsId", "permissionId")
|
|||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('User'),
|
roles_permissionsId: getId('User'),
|
||||||
permissionId: getId('CREATE_GALLERIES'),
|
permissionId: getId('CREATE_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('User'),
|
roles_permissionsId: getId('User'),
|
||||||
permissionId: getId('READ_GALLERIES'),
|
permissionId: getId('READ_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('User'),
|
roles_permissionsId: getId('User'),
|
||||||
permissionId: getId('UPDATE_GALLERIES'),
|
permissionId: getId('UPDATE_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('User'),
|
roles_permissionsId: getId('User'),
|
||||||
permissionId: getId('DELETE_GALLERIES'),
|
permissionId: getId('DELETE_PERIODS'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -271,25 +271,25 @@ primary key ("roles_permissionsId", "permissionId")
|
|||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('Administrator'),
|
roles_permissionsId: getId('Administrator'),
|
||||||
permissionId: getId('CREATE_GALLERIES'),
|
permissionId: getId('CREATE_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('Administrator'),
|
roles_permissionsId: getId('Administrator'),
|
||||||
permissionId: getId('READ_GALLERIES'),
|
permissionId: getId('READ_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('Administrator'),
|
roles_permissionsId: getId('Administrator'),
|
||||||
permissionId: getId('UPDATE_GALLERIES'),
|
permissionId: getId('UPDATE_PERIODS'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
roles_permissionsId: getId('Administrator'),
|
roles_permissionsId: getId('Administrator'),
|
||||||
permissionId: getId('DELETE_GALLERIES'),
|
permissionId: getId('DELETE_PERIODS'),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
103
backend/src/db/seeders/20251016065719.js
Normal file
103
backend/src/db/seeders/20251016065719.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
const { v4: uuid } = require('uuid');
|
||||||
|
const db = require('../models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const config = require('../../config');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* @param{import("sequelize").QueryInterface} queryInterface
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
async up(queryInterface) {
|
||||||
|
const createdAt = new Date();
|
||||||
|
const updatedAt = new Date();
|
||||||
|
|
||||||
|
/** @type {Map<string, string>} */
|
||||||
|
const idMap = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} key
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function getId(key) {
|
||||||
|
if (idMap.has(key)) {
|
||||||
|
return idMap.get(key);
|
||||||
|
}
|
||||||
|
const id = uuid();
|
||||||
|
idMap.set(key, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
function createPermissions(name) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: getId(`CREATE_${name.toUpperCase()}`),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
name: `CREATE_${name.toUpperCase()}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: getId(`READ_${name.toUpperCase()}`),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
name: `READ_${name.toUpperCase()}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: getId(`UPDATE_${name.toUpperCase()}`),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
name: `UPDATE_${name.toUpperCase()}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: getId(`DELETE_${name.toUpperCase()}`),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
name: `DELETE_${name.toUpperCase()}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const entities = ['periods'];
|
||||||
|
|
||||||
|
const previousValues = ['galleries'];
|
||||||
|
const createdPreviousPermissions =
|
||||||
|
previousValues.flatMap(createPermissions);
|
||||||
|
const namesPreviousPermissions = createdPreviousPermissions.map(
|
||||||
|
(p) => p.name,
|
||||||
|
);
|
||||||
|
|
||||||
|
const createdPermissions = entities.flatMap(createPermissions);
|
||||||
|
|
||||||
|
// Add permissions to database
|
||||||
|
await queryInterface.bulkInsert('permissions', createdPermissions);
|
||||||
|
// Get permissions ids
|
||||||
|
const permissionsIds = createdPermissions.map((p) => p.id);
|
||||||
|
// Get admin role
|
||||||
|
const adminRole = await db.roles.findOne({
|
||||||
|
where: { name: config.roles.admin },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (adminRole) {
|
||||||
|
// Add permissions to admin role if it exists
|
||||||
|
await adminRole.addPermissions(permissionsIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove previous permissions
|
||||||
|
await db.permissions.destroy({
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
[Sequelize.Op.in]: namesPreviousPermissions,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
down: async (queryInterface, Sequelize) => {
|
||||||
|
await queryInterface.bulkDelete(
|
||||||
|
'permissions',
|
||||||
|
entities.flatMap(createPermissions),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -21,7 +21,7 @@ const usersRoutes = require('./routes/users');
|
|||||||
|
|
||||||
const archival_itemsRoutes = require('./routes/archival_items');
|
const archival_itemsRoutes = require('./routes/archival_items');
|
||||||
|
|
||||||
const galleriesRoutes = require('./routes/galleries');
|
const periodsRoutes = require('./routes/periods');
|
||||||
|
|
||||||
const tagsRoutes = require('./routes/tags');
|
const tagsRoutes = require('./routes/tags');
|
||||||
|
|
||||||
@ -107,9 +107,9 @@ app.use(
|
|||||||
);
|
);
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
'/api/galleries',
|
'/api/periods',
|
||||||
passport.authenticate('jwt', { session: false }),
|
passport.authenticate('jwt', { session: false }),
|
||||||
galleriesRoutes,
|
periodsRoutes,
|
||||||
);
|
);
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
|
|||||||
@ -26,9 +26,6 @@ router.use(checkCrudPermissions('archival_items'));
|
|||||||
* description:
|
* description:
|
||||||
* type: string
|
* type: string
|
||||||
* default: description
|
* default: description
|
||||||
* period_to:
|
|
||||||
* type: string
|
|
||||||
* default: period_to
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -316,7 +313,7 @@ router.get(
|
|||||||
currentUser,
|
currentUser,
|
||||||
});
|
});
|
||||||
if (filetype && filetype === 'csv') {
|
if (filetype && filetype === 'csv') {
|
||||||
const fields = ['id', 'label', 'description', 'period_to', 'period_from'];
|
const fields = ['id', 'label', 'description'];
|
||||||
const opts = { fields };
|
const opts = { fields };
|
||||||
try {
|
try {
|
||||||
const csv = parse(payload.rows, opts);
|
const csv = parse(payload.rows, opts);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
|
||||||
const GalleriesService = require('../services/galleries');
|
const PeriodsService = require('../services/periods');
|
||||||
const GalleriesDBApi = require('../db/api/galleries');
|
const PeriodsDBApi = require('../db/api/periods');
|
||||||
const wrapAsync = require('../helpers').wrapAsync;
|
const wrapAsync = require('../helpers').wrapAsync;
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@ -10,13 +10,13 @@ const { parse } = require('json2csv');
|
|||||||
|
|
||||||
const { checkCrudPermissions } = require('../middlewares/check-permissions');
|
const { checkCrudPermissions } = require('../middlewares/check-permissions');
|
||||||
|
|
||||||
router.use(checkCrudPermissions('galleries'));
|
router.use(checkCrudPermissions('periods'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* components:
|
* components:
|
||||||
* schemas:
|
* schemas:
|
||||||
* Galleries:
|
* Periods:
|
||||||
* type: object
|
* type: object
|
||||||
* properties:
|
* properties:
|
||||||
|
|
||||||
@ -29,17 +29,17 @@ router.use(checkCrudPermissions('galleries'));
|
|||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* tags:
|
* tags:
|
||||||
* name: Galleries
|
* name: Periods
|
||||||
* description: The Galleries managing API
|
* description: The Periods managing API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries:
|
* /api/periods:
|
||||||
* post:
|
* post:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Add new item
|
* summary: Add new item
|
||||||
* description: Add new item
|
* description: Add new item
|
||||||
* requestBody:
|
* requestBody:
|
||||||
@ -51,14 +51,14 @@ router.use(checkCrudPermissions('galleries'));
|
|||||||
* data:
|
* data:
|
||||||
* description: Data of the updated item
|
* description: Data of the updated item
|
||||||
* type: object
|
* type: object
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: The item was successfully added
|
* description: The item was successfully added
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 405:
|
* 405:
|
||||||
@ -73,7 +73,7 @@ router.post(
|
|||||||
req.headers.referer ||
|
req.headers.referer ||
|
||||||
`${req.protocol}://${req.hostname}${req.originalUrl}`;
|
`${req.protocol}://${req.hostname}${req.originalUrl}`;
|
||||||
const link = new URL(referer);
|
const link = new URL(referer);
|
||||||
await GalleriesService.create(
|
await PeriodsService.create(
|
||||||
req.body.data,
|
req.body.data,
|
||||||
req.currentUser,
|
req.currentUser,
|
||||||
true,
|
true,
|
||||||
@ -90,7 +90,7 @@ router.post(
|
|||||||
* post:
|
* post:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Bulk import items
|
* summary: Bulk import items
|
||||||
* description: Bulk import items
|
* description: Bulk import items
|
||||||
* requestBody:
|
* requestBody:
|
||||||
@ -103,14 +103,14 @@ router.post(
|
|||||||
* description: Data of the updated items
|
* description: Data of the updated items
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: The items were successfully imported
|
* description: The items were successfully imported
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 405:
|
* 405:
|
||||||
@ -126,7 +126,7 @@ router.post(
|
|||||||
req.headers.referer ||
|
req.headers.referer ||
|
||||||
`${req.protocol}://${req.hostname}${req.originalUrl}`;
|
`${req.protocol}://${req.hostname}${req.originalUrl}`;
|
||||||
const link = new URL(referer);
|
const link = new URL(referer);
|
||||||
await GalleriesService.bulkImport(req, res, true, link.host);
|
await PeriodsService.bulkImport(req, res, true, link.host);
|
||||||
const payload = true;
|
const payload = true;
|
||||||
res.status(200).send(payload);
|
res.status(200).send(payload);
|
||||||
}),
|
}),
|
||||||
@ -134,11 +134,11 @@ router.post(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/{id}:
|
* /api/periods/{id}:
|
||||||
* put:
|
* put:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Update the data of the selected item
|
* summary: Update the data of the selected item
|
||||||
* description: Update the data of the selected item
|
* description: Update the data of the selected item
|
||||||
* parameters:
|
* parameters:
|
||||||
@ -161,7 +161,7 @@ router.post(
|
|||||||
* data:
|
* data:
|
||||||
* description: Data of the updated item
|
* description: Data of the updated item
|
||||||
* type: object
|
* type: object
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* required:
|
* required:
|
||||||
* - id
|
* - id
|
||||||
* responses:
|
* responses:
|
||||||
@ -170,7 +170,7 @@ router.post(
|
|||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 400:
|
* 400:
|
||||||
* description: Invalid ID supplied
|
* description: Invalid ID supplied
|
||||||
* 401:
|
* 401:
|
||||||
@ -183,7 +183,7 @@ router.post(
|
|||||||
router.put(
|
router.put(
|
||||||
'/:id',
|
'/:id',
|
||||||
wrapAsync(async (req, res) => {
|
wrapAsync(async (req, res) => {
|
||||||
await GalleriesService.update(req.body.data, req.body.id, req.currentUser);
|
await PeriodsService.update(req.body.data, req.body.id, req.currentUser);
|
||||||
const payload = true;
|
const payload = true;
|
||||||
res.status(200).send(payload);
|
res.status(200).send(payload);
|
||||||
}),
|
}),
|
||||||
@ -191,11 +191,11 @@ router.put(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/{id}:
|
* /api/periods/{id}:
|
||||||
* delete:
|
* delete:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Delete the selected item
|
* summary: Delete the selected item
|
||||||
* description: Delete the selected item
|
* description: Delete the selected item
|
||||||
* parameters:
|
* parameters:
|
||||||
@ -211,7 +211,7 @@ router.put(
|
|||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 400:
|
* 400:
|
||||||
* description: Invalid ID supplied
|
* description: Invalid ID supplied
|
||||||
* 401:
|
* 401:
|
||||||
@ -224,7 +224,7 @@ router.put(
|
|||||||
router.delete(
|
router.delete(
|
||||||
'/:id',
|
'/:id',
|
||||||
wrapAsync(async (req, res) => {
|
wrapAsync(async (req, res) => {
|
||||||
await GalleriesService.remove(req.params.id, req.currentUser);
|
await PeriodsService.remove(req.params.id, req.currentUser);
|
||||||
const payload = true;
|
const payload = true;
|
||||||
res.status(200).send(payload);
|
res.status(200).send(payload);
|
||||||
}),
|
}),
|
||||||
@ -232,11 +232,11 @@ router.delete(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/deleteByIds:
|
* /api/periods/deleteByIds:
|
||||||
* post:
|
* post:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Delete the selected item list
|
* summary: Delete the selected item list
|
||||||
* description: Delete the selected item list
|
* description: Delete the selected item list
|
||||||
* requestBody:
|
* requestBody:
|
||||||
@ -254,7 +254,7 @@ router.delete(
|
|||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 404:
|
* 404:
|
||||||
@ -265,7 +265,7 @@ router.delete(
|
|||||||
router.post(
|
router.post(
|
||||||
'/deleteByIds',
|
'/deleteByIds',
|
||||||
wrapAsync(async (req, res) => {
|
wrapAsync(async (req, res) => {
|
||||||
await GalleriesService.deleteByIds(req.body.data, req.currentUser);
|
await PeriodsService.deleteByIds(req.body.data, req.currentUser);
|
||||||
const payload = true;
|
const payload = true;
|
||||||
res.status(200).send(payload);
|
res.status(200).send(payload);
|
||||||
}),
|
}),
|
||||||
@ -273,22 +273,22 @@ router.post(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries:
|
* /api/periods:
|
||||||
* get:
|
* get:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Get all galleries
|
* summary: Get all periods
|
||||||
* description: Get all galleries
|
* description: Get all periods
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: Galleries list successfully received
|
* description: Periods list successfully received
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 404:
|
* 404:
|
||||||
@ -302,9 +302,9 @@ router.get(
|
|||||||
const filetype = req.query.filetype;
|
const filetype = req.query.filetype;
|
||||||
|
|
||||||
const currentUser = req.currentUser;
|
const currentUser = req.currentUser;
|
||||||
const payload = await GalleriesDBApi.findAll(req.query, { currentUser });
|
const payload = await PeriodsDBApi.findAll(req.query, { currentUser });
|
||||||
if (filetype && filetype === 'csv') {
|
if (filetype && filetype === 'csv') {
|
||||||
const fields = ['id', 'name'];
|
const fields = ['id', 'name', 'period_from', 'period_to'];
|
||||||
const opts = { fields };
|
const opts = { fields };
|
||||||
try {
|
try {
|
||||||
const csv = parse(payload.rows, opts);
|
const csv = parse(payload.rows, opts);
|
||||||
@ -321,22 +321,22 @@ router.get(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/count:
|
* /api/periods/count:
|
||||||
* get:
|
* get:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Count all galleries
|
* summary: Count all periods
|
||||||
* description: Count all galleries
|
* description: Count all periods
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: Galleries count successfully received
|
* description: Periods count successfully received
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 404:
|
* 404:
|
||||||
@ -348,7 +348,7 @@ router.get(
|
|||||||
'/count',
|
'/count',
|
||||||
wrapAsync(async (req, res) => {
|
wrapAsync(async (req, res) => {
|
||||||
const currentUser = req.currentUser;
|
const currentUser = req.currentUser;
|
||||||
const payload = await GalleriesDBApi.findAll(req.query, null, {
|
const payload = await PeriodsDBApi.findAll(req.query, null, {
|
||||||
countOnly: true,
|
countOnly: true,
|
||||||
currentUser,
|
currentUser,
|
||||||
});
|
});
|
||||||
@ -359,22 +359,22 @@ router.get(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/autocomplete:
|
* /api/periods/autocomplete:
|
||||||
* get:
|
* get:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Find all galleries that match search criteria
|
* summary: Find all periods that match search criteria
|
||||||
* description: Find all galleries that match search criteria
|
* description: Find all periods that match search criteria
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: Galleries list successfully received
|
* description: Periods list successfully received
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 401:
|
* 401:
|
||||||
* $ref: "#/components/responses/UnauthorizedError"
|
* $ref: "#/components/responses/UnauthorizedError"
|
||||||
* 404:
|
* 404:
|
||||||
@ -383,7 +383,7 @@ router.get(
|
|||||||
* description: Some server error
|
* description: Some server error
|
||||||
*/
|
*/
|
||||||
router.get('/autocomplete', async (req, res) => {
|
router.get('/autocomplete', async (req, res) => {
|
||||||
const payload = await GalleriesDBApi.findAllAutocomplete(
|
const payload = await PeriodsDBApi.findAllAutocomplete(
|
||||||
req.query.query,
|
req.query.query,
|
||||||
req.query.limit,
|
req.query.limit,
|
||||||
req.query.offset,
|
req.query.offset,
|
||||||
@ -394,11 +394,11 @@ router.get('/autocomplete', async (req, res) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @swagger
|
* @swagger
|
||||||
* /api/galleries/{id}:
|
* /api/periods/{id}:
|
||||||
* get:
|
* get:
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
* tags: [Galleries]
|
* tags: [Periods]
|
||||||
* summary: Get selected item
|
* summary: Get selected item
|
||||||
* description: Get selected item
|
* description: Get selected item
|
||||||
* parameters:
|
* parameters:
|
||||||
@ -414,7 +414,7 @@ router.get('/autocomplete', async (req, res) => {
|
|||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: "#/components/schemas/Galleries"
|
* $ref: "#/components/schemas/Periods"
|
||||||
* 400:
|
* 400:
|
||||||
* description: Invalid ID supplied
|
* description: Invalid ID supplied
|
||||||
* 401:
|
* 401:
|
||||||
@ -427,7 +427,7 @@ router.get('/autocomplete', async (req, res) => {
|
|||||||
router.get(
|
router.get(
|
||||||
'/:id',
|
'/:id',
|
||||||
wrapAsync(async (req, res) => {
|
wrapAsync(async (req, res) => {
|
||||||
const payload = await GalleriesDBApi.findBy({ id: req.params.id });
|
const payload = await PeriodsDBApi.findBy({ id: req.params.id });
|
||||||
|
|
||||||
res.status(200).send(payload);
|
res.status(200).send(payload);
|
||||||
}),
|
}),
|
||||||
@ -1,5 +1,5 @@
|
|||||||
const db = require('../db/models');
|
const db = require('../db/models');
|
||||||
const GalleriesDBApi = require('../db/api/galleries');
|
const PeriodsDBApi = require('../db/api/periods');
|
||||||
const processFile = require('../middlewares/upload');
|
const processFile = require('../middlewares/upload');
|
||||||
const ValidationError = require('./notifications/errors/validation');
|
const ValidationError = require('./notifications/errors/validation');
|
||||||
const csv = require('csv-parser');
|
const csv = require('csv-parser');
|
||||||
@ -7,11 +7,11 @@ const axios = require('axios');
|
|||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
|
|
||||||
module.exports = class GalleriesService {
|
module.exports = class PeriodsService {
|
||||||
static async create(data, currentUser) {
|
static async create(data, currentUser) {
|
||||||
const transaction = await db.sequelize.transaction();
|
const transaction = await db.sequelize.transaction();
|
||||||
try {
|
try {
|
||||||
await GalleriesDBApi.create(data, {
|
await PeriodsDBApi.create(data, {
|
||||||
currentUser,
|
currentUser,
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -44,7 +44,7 @@ module.exports = class GalleriesService {
|
|||||||
.on('error', (error) => reject(error));
|
.on('error', (error) => reject(error));
|
||||||
});
|
});
|
||||||
|
|
||||||
await GalleriesDBApi.bulkImport(results, {
|
await PeriodsDBApi.bulkImport(results, {
|
||||||
transaction,
|
transaction,
|
||||||
ignoreDuplicates: true,
|
ignoreDuplicates: true,
|
||||||
validate: true,
|
validate: true,
|
||||||
@ -61,19 +61,19 @@ module.exports = class GalleriesService {
|
|||||||
static async update(data, id, currentUser) {
|
static async update(data, id, currentUser) {
|
||||||
const transaction = await db.sequelize.transaction();
|
const transaction = await db.sequelize.transaction();
|
||||||
try {
|
try {
|
||||||
let galleries = await GalleriesDBApi.findBy({ id }, { transaction });
|
let periods = await PeriodsDBApi.findBy({ id }, { transaction });
|
||||||
|
|
||||||
if (!galleries) {
|
if (!periods) {
|
||||||
throw new ValidationError('galleriesNotFound');
|
throw new ValidationError('periodsNotFound');
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedGalleries = await GalleriesDBApi.update(id, data, {
|
const updatedPeriods = await PeriodsDBApi.update(id, data, {
|
||||||
currentUser,
|
currentUser,
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
await transaction.commit();
|
await transaction.commit();
|
||||||
return updatedGalleries;
|
return updatedPeriods;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await transaction.rollback();
|
await transaction.rollback();
|
||||||
throw error;
|
throw error;
|
||||||
@ -84,7 +84,7 @@ module.exports = class GalleriesService {
|
|||||||
const transaction = await db.sequelize.transaction();
|
const transaction = await db.sequelize.transaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await GalleriesDBApi.deleteByIds(ids, {
|
await PeriodsDBApi.deleteByIds(ids, {
|
||||||
currentUser,
|
currentUser,
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -100,7 +100,7 @@ module.exports = class GalleriesService {
|
|||||||
const transaction = await db.sequelize.transaction();
|
const transaction = await db.sequelize.transaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await GalleriesDBApi.remove(id, {
|
await PeriodsDBApi.remove(id, {
|
||||||
currentUser,
|
currentUser,
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -43,9 +43,9 @@ module.exports = class SearchService {
|
|||||||
const tableColumns = {
|
const tableColumns = {
|
||||||
users: ['firstName', 'lastName', 'phoneNumber', 'email'],
|
users: ['firstName', 'lastName', 'phoneNumber', 'email'],
|
||||||
|
|
||||||
archival_items: ['label', 'description', 'period_to'],
|
archival_items: ['label', 'description'],
|
||||||
|
|
||||||
galleries: ['name'],
|
periods: ['name'],
|
||||||
|
|
||||||
tags: ['name'],
|
tags: ['name'],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -127,28 +127,6 @@ const CardArchival_items = ({
|
|||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex justify-between gap-x-4 py-3'>
|
|
||||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
|
||||||
Period From
|
|
||||||
</dt>
|
|
||||||
<dd className='flex items-start gap-x-2'>
|
|
||||||
<div className='font-medium line-clamp-4'>
|
|
||||||
{dataFormatter.dateFormatter(item.period_from)}
|
|
||||||
</div>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='flex justify-between gap-x-4 py-3'>
|
|
||||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
|
||||||
Period To
|
|
||||||
</dt>
|
|
||||||
<dd className='flex items-start gap-x-2'>
|
|
||||||
<div className='font-medium line-clamp-4'>
|
|
||||||
{item.period_to}
|
|
||||||
</div>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='flex justify-between gap-x-4 py-3'>
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
<dt className=' text-gray-500 dark:text-dark-600'>Tags</dt>
|
<dt className=' text-gray-500 dark:text-dark-600'>Tags</dt>
|
||||||
<dd className='flex items-start gap-x-2'>
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
|||||||
@ -89,18 +89,6 @@ const ListArchival_items = ({
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'flex-1 px-3'}>
|
|
||||||
<p className={'text-xs text-gray-500 '}>Period From</p>
|
|
||||||
<p className={'line-clamp-2'}>
|
|
||||||
{dataFormatter.dateFormatter(item.period_from)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={'flex-1 px-3'}>
|
|
||||||
<p className={'text-xs text-gray-500 '}>Period To</p>
|
|
||||||
<p className={'line-clamp-2'}>{item.period_to}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={'flex-1 px-3'}>
|
<div className={'flex-1 px-3'}>
|
||||||
<p className={'text-xs text-gray-500 '}>Tags</p>
|
<p className={'text-xs text-gray-500 '}>Tags</p>
|
||||||
<p className={'line-clamp-2'}>
|
<p className={'line-clamp-2'}>
|
||||||
|
|||||||
@ -96,34 +96,6 @@ export const loadColumns = async (
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
field: 'period_from',
|
|
||||||
headerName: 'Period From',
|
|
||||||
flex: 1,
|
|
||||||
minWidth: 120,
|
|
||||||
filterable: false,
|
|
||||||
headerClassName: 'datagrid--header',
|
|
||||||
cellClassName: 'datagrid--cell',
|
|
||||||
|
|
||||||
editable: hasUpdatePermission,
|
|
||||||
|
|
||||||
type: 'date',
|
|
||||||
valueGetter: (params: GridValueGetterParams) =>
|
|
||||||
new Date(params.row.period_from),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
field: 'period_to',
|
|
||||||
headerName: 'Period To',
|
|
||||||
flex: 1,
|
|
||||||
minWidth: 120,
|
|
||||||
filterable: false,
|
|
||||||
headerClassName: 'datagrid--header',
|
|
||||||
cellClassName: 'datagrid--cell',
|
|
||||||
|
|
||||||
editable: hasUpdatePermission,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
field: 'tags',
|
field: 'tags',
|
||||||
headerName: 'Tags',
|
headerName: 'Tags',
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import Link from 'next/link';
|
|||||||
import { hasPermission } from '../../helpers/userPermissions';
|
import { hasPermission } from '../../helpers/userPermissions';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
galleries: any[];
|
periods: any[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
onDelete: (id: string) => void;
|
onDelete: (id: string) => void;
|
||||||
currentPage: number;
|
currentPage: number;
|
||||||
@ -19,8 +19,8 @@ type Props = {
|
|||||||
onPageChange: (page: number) => void;
|
onPageChange: (page: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CardGalleries = ({
|
const CardPeriods = ({
|
||||||
galleries,
|
periods,
|
||||||
loading,
|
loading,
|
||||||
onDelete,
|
onDelete,
|
||||||
currentPage,
|
currentPage,
|
||||||
@ -36,7 +36,7 @@ const CardGalleries = ({
|
|||||||
const focusRing = useAppSelector((state) => state.style.focusRingColor);
|
const focusRing = useAppSelector((state) => state.style.focusRingColor);
|
||||||
|
|
||||||
const currentUser = useAppSelector((state) => state.auth.currentUser);
|
const currentUser = useAppSelector((state) => state.auth.currentUser);
|
||||||
const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_GALLERIES');
|
const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_PERIODS');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'p-4'}>
|
<div className={'p-4'}>
|
||||||
@ -46,7 +46,7 @@ const CardGalleries = ({
|
|||||||
className='grid grid-cols-1 gap-x-6 gap-y-8 lg:grid-cols-3 2xl:grid-cols-4 xl:gap-x-8'
|
className='grid grid-cols-1 gap-x-6 gap-y-8 lg:grid-cols-3 2xl:grid-cols-4 xl:gap-x-8'
|
||||||
>
|
>
|
||||||
{!loading &&
|
{!loading &&
|
||||||
galleries.map((item, index) => (
|
periods.map((item, index) => (
|
||||||
<li
|
<li
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={`overflow-hidden ${
|
className={`overflow-hidden ${
|
||||||
@ -56,27 +56,21 @@ const CardGalleries = ({
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex items-center ${bgColor} p-6 md:p-0 md:block gap-x-4 border-b border-gray-900/5 bg-gray-50 dark:bg-dark-800 relative`}
|
className={`flex items-center ${bgColor} p-6 gap-x-4 border-b border-gray-900/5 bg-gray-50 dark:bg-dark-800 relative`}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/galleries/galleries-view/?id=${item.id}`}
|
href={`/periods/periods-view/?id=${item.id}`}
|
||||||
className={'cursor-pointer'}
|
className='text-lg font-bold leading-6 line-clamp-1'
|
||||||
>
|
>
|
||||||
<ImageField
|
{item.id}
|
||||||
name={'Avatar'}
|
|
||||||
image={item.background_image}
|
|
||||||
className='w-12 h-12 md:w-full md:h-44 rounded-lg md:rounded-b-none overflow-hidden ring-1 ring-gray-900/10'
|
|
||||||
imageClassName='h-full w-full flex-none rounded-lg md:rounded-b-none bg-white object-cover'
|
|
||||||
/>
|
|
||||||
<p className={'px-6 py-2 font-semibold'}>{item.id}</p>
|
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div className='ml-auto md:absolute md:top-0 md:right-0 '>
|
<div className='ml-auto '>
|
||||||
<ListActionsPopover
|
<ListActionsPopover
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
itemId={item.id}
|
itemId={item.id}
|
||||||
pathEdit={`/galleries/galleries-edit/?id=${item.id}`}
|
pathEdit={`/periods/periods-edit/?id=${item.id}`}
|
||||||
pathView={`/galleries/galleries-view/?id=${item.id}`}
|
pathView={`/periods/periods-view/?id=${item.id}`}
|
||||||
hasUpdatePermission={hasUpdatePermission}
|
hasUpdatePermission={hasUpdatePermission}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -104,22 +98,29 @@ const CardGalleries = ({
|
|||||||
|
|
||||||
<div className='flex justify-between gap-x-4 py-3'>
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
<dt className=' text-gray-500 dark:text-dark-600'>
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
Background Image
|
Period From
|
||||||
</dt>
|
</dt>
|
||||||
<dd className='flex items-start gap-x-2'>
|
<dd className='flex items-start gap-x-2'>
|
||||||
<div className='font-medium'>
|
<div className='font-medium line-clamp-4'>
|
||||||
<ImageField
|
{dataFormatter.dateTimeFormatter(item.period_from)}
|
||||||
name={'Avatar'}
|
</div>
|
||||||
image={item.background_image}
|
</dd>
|
||||||
className='mx-auto w-8 h-8'
|
</div>
|
||||||
/>
|
|
||||||
|
<div className='flex justify-between gap-x-4 py-3'>
|
||||||
|
<dt className=' text-gray-500 dark:text-dark-600'>
|
||||||
|
Period To
|
||||||
|
</dt>
|
||||||
|
<dd className='flex items-start gap-x-2'>
|
||||||
|
<div className='font-medium line-clamp-4'>
|
||||||
|
{dataFormatter.dateTimeFormatter(item.period_to)}
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
{!loading && galleries.length === 0 && (
|
{!loading && periods.length === 0 && (
|
||||||
<div className='col-span-full flex items-center justify-center h-40'>
|
<div className='col-span-full flex items-center justify-center h-40'>
|
||||||
<p className=''>No data to display</p>
|
<p className=''>No data to display</p>
|
||||||
</div>
|
</div>
|
||||||
@ -136,4 +137,4 @@ const CardGalleries = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CardGalleries;
|
export default CardPeriods;
|
||||||
@ -12,7 +12,7 @@ import Link from 'next/link';
|
|||||||
import { hasPermission } from '../../helpers/userPermissions';
|
import { hasPermission } from '../../helpers/userPermissions';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
galleries: any[];
|
periods: any[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
onDelete: (id: string) => void;
|
onDelete: (id: string) => void;
|
||||||
currentPage: number;
|
currentPage: number;
|
||||||
@ -20,8 +20,8 @@ type Props = {
|
|||||||
onPageChange: (page: number) => void;
|
onPageChange: (page: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ListGalleries = ({
|
const ListPeriods = ({
|
||||||
galleries,
|
periods,
|
||||||
loading,
|
loading,
|
||||||
onDelete,
|
onDelete,
|
||||||
currentPage,
|
currentPage,
|
||||||
@ -29,7 +29,7 @@ const ListGalleries = ({
|
|||||||
onPageChange,
|
onPageChange,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const currentUser = useAppSelector((state) => state.auth.currentUser);
|
const currentUser = useAppSelector((state) => state.auth.currentUser);
|
||||||
const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_GALLERIES');
|
const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_PERIODS');
|
||||||
|
|
||||||
const corners = useAppSelector((state) => state.style.corners);
|
const corners = useAppSelector((state) => state.style.corners);
|
||||||
const bgColor = useAppSelector((state) => state.style.cardsColor);
|
const bgColor = useAppSelector((state) => state.style.cardsColor);
|
||||||
@ -39,23 +39,14 @@ const ListGalleries = ({
|
|||||||
<div className='relative overflow-x-auto p-4 space-y-4'>
|
<div className='relative overflow-x-auto p-4 space-y-4'>
|
||||||
{loading && <LoadingSpinner />}
|
{loading && <LoadingSpinner />}
|
||||||
{!loading &&
|
{!loading &&
|
||||||
galleries.map((item) => (
|
periods.map((item) => (
|
||||||
<div key={item.id}>
|
<div key={item.id}>
|
||||||
<CardBox hasTable isList className={'rounded shadow-none'}>
|
<CardBox hasTable isList className={'rounded shadow-none'}>
|
||||||
<div
|
<div
|
||||||
className={`flex rounded dark:bg-dark-900 border border-stone-300 items-center overflow-hidden`}
|
className={`flex rounded dark:bg-dark-900 border border-stone-300 items-center overflow-hidden`}
|
||||||
>
|
>
|
||||||
<ImageField
|
|
||||||
name={'Avatar'}
|
|
||||||
image={item.background_image}
|
|
||||||
className='w-24 h-24 rounded-l overflow-hidden hidden md:block'
|
|
||||||
imageClassName={
|
|
||||||
'rounded-l rounded-r-none h-full object-cover'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href={`/galleries/galleries-view/?id=${item.id}`}
|
href={`/periods/periods-view/?id=${item.id}`}
|
||||||
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'
|
||||||
}
|
}
|
||||||
@ -77,28 +68,31 @@ const ListGalleries = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'flex-1 px-3'}>
|
<div className={'flex-1 px-3'}>
|
||||||
<p className={'text-xs text-gray-500 '}>
|
<p className={'text-xs text-gray-500 '}>Period From</p>
|
||||||
Background Image
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter.dateTimeFormatter(item.period_from)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={'flex-1 px-3'}>
|
||||||
|
<p className={'text-xs text-gray-500 '}>Period To</p>
|
||||||
|
<p className={'line-clamp-2'}>
|
||||||
|
{dataFormatter.dateTimeFormatter(item.period_to)}
|
||||||
</p>
|
</p>
|
||||||
<ImageField
|
|
||||||
name={'Avatar'}
|
|
||||||
image={item.background_image}
|
|
||||||
className='mx-auto w-8 h-8'
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<ListActionsPopover
|
<ListActionsPopover
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
itemId={item.id}
|
itemId={item.id}
|
||||||
pathEdit={`/galleries/galleries-edit/?id=${item.id}`}
|
pathEdit={`/periods/periods-edit/?id=${item.id}`}
|
||||||
pathView={`/galleries/galleries-view/?id=${item.id}`}
|
pathView={`/periods/periods-view/?id=${item.id}`}
|
||||||
hasUpdatePermission={hasUpdatePermission}
|
hasUpdatePermission={hasUpdatePermission}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{!loading && galleries.length === 0 && (
|
{!loading && periods.length === 0 && (
|
||||||
<div className='col-span-full flex items-center justify-center h-40'>
|
<div className='col-span-full flex items-center justify-center h-40'>
|
||||||
<p className=''>No data to display</p>
|
<p className=''>No data to display</p>
|
||||||
</div>
|
</div>
|
||||||
@ -115,4 +109,4 @@ const ListGalleries = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ListGalleries;
|
export default ListPeriods;
|
||||||
@ -10,19 +10,19 @@ import {
|
|||||||
deleteItem,
|
deleteItem,
|
||||||
setRefetch,
|
setRefetch,
|
||||||
deleteItemsByIds,
|
deleteItemsByIds,
|
||||||
} from '../../stores/galleries/galleriesSlice';
|
} from '../../stores/periods/periodsSlice';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { Field, Form, Formik } from 'formik';
|
import { Field, Form, Formik } from 'formik';
|
||||||
import { DataGrid, GridColDef } from '@mui/x-data-grid';
|
import { DataGrid, GridColDef } from '@mui/x-data-grid';
|
||||||
import { loadColumns } from './configureGalleriesCols';
|
import { loadColumns } from './configurePeriodsCols';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import dataFormatter from '../../helpers/dataFormatter';
|
import dataFormatter from '../../helpers/dataFormatter';
|
||||||
import { dataGridStyles } from '../../styles';
|
import { dataGridStyles } from '../../styles';
|
||||||
|
|
||||||
const perPage = 10;
|
const perPage = 10;
|
||||||
|
|
||||||
const TableSampleGalleries = ({
|
const TableSamplePeriods = ({
|
||||||
filterItems,
|
filterItems,
|
||||||
setFilterItems,
|
setFilterItems,
|
||||||
filters,
|
filters,
|
||||||
@ -47,12 +47,12 @@ const TableSampleGalleries = ({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
galleries,
|
periods,
|
||||||
loading,
|
loading,
|
||||||
count,
|
count,
|
||||||
notify: galleriesNotify,
|
notify: periodsNotify,
|
||||||
refetch,
|
refetch,
|
||||||
} = useAppSelector((state) => state.galleries);
|
} = useAppSelector((state) => state.periods);
|
||||||
const { currentUser } = useAppSelector((state) => state.auth);
|
const { currentUser } = useAppSelector((state) => state.auth);
|
||||||
const focusRing = useAppSelector((state) => state.style.focusRingColor);
|
const focusRing = useAppSelector((state) => state.style.focusRingColor);
|
||||||
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
|
const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
|
||||||
@ -73,13 +73,10 @@ const TableSampleGalleries = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (galleriesNotify.showNotification) {
|
if (periodsNotify.showNotification) {
|
||||||
notify(
|
notify(periodsNotify.typeNotification, periodsNotify.textNotification);
|
||||||
galleriesNotify.typeNotification,
|
|
||||||
galleriesNotify.textNotification,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [galleriesNotify.showNotification]);
|
}, [periodsNotify.showNotification]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentUser) return;
|
if (!currentUser) return;
|
||||||
@ -184,7 +181,7 @@ const TableSampleGalleries = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentUser) return;
|
if (!currentUser) return;
|
||||||
|
|
||||||
loadColumns(handleDeleteModalAction, `galleries`, currentUser).then(
|
loadColumns(handleDeleteModalAction, `periods`, currentUser).then(
|
||||||
(newCols) => setColumns(newCols),
|
(newCols) => setColumns(newCols),
|
||||||
);
|
);
|
||||||
}, [currentUser]);
|
}, [currentUser]);
|
||||||
@ -218,7 +215,7 @@ const TableSampleGalleries = ({
|
|||||||
sx={dataGridStyles}
|
sx={dataGridStyles}
|
||||||
className={'datagrid--table'}
|
className={'datagrid--table'}
|
||||||
getRowClassName={() => `datagrid--row`}
|
getRowClassName={() => `datagrid--row`}
|
||||||
rows={galleries ?? []}
|
rows={periods ?? []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
initialState={{
|
initialState={{
|
||||||
pagination: {
|
pagination: {
|
||||||
@ -481,4 +478,4 @@ const TableSampleGalleries = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TableSampleGalleries;
|
export default TableSamplePeriods;
|
||||||
@ -35,7 +35,7 @@ export const loadColumns = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasUpdatePermission = hasPermission(user, 'UPDATE_GALLERIES');
|
const hasUpdatePermission = hasPermission(user, 'UPDATE_PERIODS');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -70,23 +70,35 @@ export const loadColumns = async (
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
field: 'background_image',
|
field: 'period_from',
|
||||||
headerName: 'Background Image',
|
headerName: 'Period From',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
filterable: false,
|
filterable: false,
|
||||||
headerClassName: 'datagrid--header',
|
headerClassName: 'datagrid--header',
|
||||||
cellClassName: 'datagrid--cell',
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
editable: false,
|
editable: hasUpdatePermission,
|
||||||
sortable: false,
|
|
||||||
renderCell: (params: GridValueGetterParams) => (
|
type: 'dateTime',
|
||||||
<ImageField
|
valueGetter: (params: GridValueGetterParams) =>
|
||||||
name={'Avatar'}
|
new Date(params.row.period_from),
|
||||||
image={params?.row?.background_image}
|
},
|
||||||
className='w-24 h-24 mx-auto lg:w-6 lg:h-6'
|
|
||||||
/>
|
{
|
||||||
),
|
field: 'period_to',
|
||||||
|
headerName: 'Period To',
|
||||||
|
flex: 1,
|
||||||
|
minWidth: 120,
|
||||||
|
filterable: false,
|
||||||
|
headerClassName: 'datagrid--header',
|
||||||
|
cellClassName: 'datagrid--cell',
|
||||||
|
|
||||||
|
editable: hasUpdatePermission,
|
||||||
|
|
||||||
|
type: 'dateTime',
|
||||||
|
valueGetter: (params: GridValueGetterParams) =>
|
||||||
|
new Date(params.row.period_to),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -101,8 +113,8 @@ export const loadColumns = async (
|
|||||||
<ListActionsPopover
|
<ListActionsPopover
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
itemId={params?.row?.id}
|
itemId={params?.row?.id}
|
||||||
pathEdit={`/galleries/galleries-edit/?id=${params?.row?.id}`}
|
pathEdit={`/periods/periods-edit/?id=${params?.row?.id}`}
|
||||||
pathView={`/galleries/galleries-view/?id=${params?.row?.id}`}
|
pathView={`/periods/periods-view/?id=${params?.row?.id}`}
|
||||||
hasUpdatePermission={hasUpdatePermission}
|
hasUpdatePermission={hasUpdatePermission}
|
||||||
/>
|
/>
|
||||||
</div>,
|
</div>,
|
||||||
@ -25,12 +25,12 @@ const menuAside: MenuAsideItem[] = [
|
|||||||
permissions: 'READ_ARCHIVAL_ITEMS',
|
permissions: 'READ_ARCHIVAL_ITEMS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: '/galleries/galleries-list',
|
href: '/periods/periods-list',
|
||||||
label: 'Galleries',
|
label: 'Periods',
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
icon: icon.mdiTable ?? icon.mdiTable,
|
icon: icon.mdiTable ?? icon.mdiTable,
|
||||||
permissions: 'READ_GALLERIES',
|
permissions: 'READ_PERIODS',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: '/tags/tags-list',
|
href: '/tags/tags-list',
|
||||||
|
|||||||
@ -44,10 +44,6 @@ const EditArchival_items = () => {
|
|||||||
|
|
||||||
isPublished: false,
|
isPublished: false,
|
||||||
|
|
||||||
period_from: new Date(),
|
|
||||||
|
|
||||||
period_to: '',
|
|
||||||
|
|
||||||
tags: [],
|
tags: [],
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
@ -135,28 +131,6 @@ const EditArchival_items = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField label='Period From'>
|
|
||||||
<DatePicker
|
|
||||||
dateFormat='yyyy-MM-dd'
|
|
||||||
selected={
|
|
||||||
initialValues.period_from
|
|
||||||
? new Date(
|
|
||||||
dayjs(initialValues.period_from).format(
|
|
||||||
'YYYY-MM-DD hh:mm',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
onChange={(date) =>
|
|
||||||
setInitialValues({ ...initialValues, period_from: date })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Period To'>
|
|
||||||
<Field name='period_to' placeholder='Period To' />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Tags' labelFor='tags'>
|
<FormField label='Tags' labelFor='tags'>
|
||||||
<Field
|
<Field
|
||||||
name='tags'
|
name='tags'
|
||||||
|
|||||||
@ -44,10 +44,6 @@ const EditArchival_itemsPage = () => {
|
|||||||
|
|
||||||
isPublished: false,
|
isPublished: false,
|
||||||
|
|
||||||
period_from: new Date(),
|
|
||||||
|
|
||||||
period_to: '',
|
|
||||||
|
|
||||||
tags: [],
|
tags: [],
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
@ -133,28 +129,6 @@ const EditArchival_itemsPage = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField label='Period From'>
|
|
||||||
<DatePicker
|
|
||||||
dateFormat='yyyy-MM-dd'
|
|
||||||
selected={
|
|
||||||
initialValues.period_from
|
|
||||||
? new Date(
|
|
||||||
dayjs(initialValues.period_from).format(
|
|
||||||
'YYYY-MM-DD hh:mm',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
onChange={(date) =>
|
|
||||||
setInitialValues({ ...initialValues, period_from: date })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Period To'>
|
|
||||||
<Field name='period_to' placeholder='Period To' />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Tags' labelFor='tags'>
|
<FormField label='Tags' labelFor='tags'>
|
||||||
<Field
|
<Field
|
||||||
name='tags'
|
name='tags'
|
||||||
|
|||||||
@ -34,7 +34,6 @@ const Archival_itemsTablesPage = () => {
|
|||||||
const [filters] = useState([
|
const [filters] = useState([
|
||||||
{ label: 'Label', title: 'label' },
|
{ label: 'Label', title: 'label' },
|
||||||
{ label: 'Description', title: 'description' },
|
{ label: 'Description', title: 'description' },
|
||||||
{ label: 'Period To', title: 'period_to' },
|
|
||||||
|
|
||||||
{ label: 'Tags', title: 'tags' },
|
{ label: 'Tags', title: 'tags' },
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -41,11 +41,6 @@ const initialValues = {
|
|||||||
|
|
||||||
isPublished: false,
|
isPublished: false,
|
||||||
|
|
||||||
period_from: '',
|
|
||||||
datePeriod_from: '',
|
|
||||||
|
|
||||||
period_to: '',
|
|
||||||
|
|
||||||
tags: [],
|
tags: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,18 +103,6 @@ const Archival_itemsNew = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField label='Period From'>
|
|
||||||
<Field
|
|
||||||
type='date'
|
|
||||||
name='period_from'
|
|
||||||
placeholder='Period From'
|
|
||||||
/>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Period To'>
|
|
||||||
<Field name='period_to' placeholder='Period To' />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Tags' labelFor='tags'>
|
<FormField label='Tags' labelFor='tags'>
|
||||||
<Field
|
<Field
|
||||||
name='tags'
|
name='tags'
|
||||||
|
|||||||
@ -34,7 +34,6 @@ const Archival_itemsTablesPage = () => {
|
|||||||
const [filters] = useState([
|
const [filters] = useState([
|
||||||
{ label: 'Label', title: 'label' },
|
{ label: 'Label', title: 'label' },
|
||||||
{ label: 'Description', title: 'description' },
|
{ label: 'Description', title: 'description' },
|
||||||
{ label: 'Period To', title: 'period_to' },
|
|
||||||
|
|
||||||
{ label: 'Tags', title: 'tags' },
|
{ label: 'Tags', title: 'tags' },
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -88,32 +88,6 @@ const Archival_itemsView = () => {
|
|||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField label='Period From'>
|
|
||||||
{archival_items.period_from ? (
|
|
||||||
<DatePicker
|
|
||||||
dateFormat='yyyy-MM-dd'
|
|
||||||
showTimeSelect
|
|
||||||
selected={
|
|
||||||
archival_items.period_from
|
|
||||||
? new Date(
|
|
||||||
dayjs(archival_items.period_from).format(
|
|
||||||
'YYYY-MM-DD hh:mm',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<p>No Period From</p>
|
|
||||||
)}
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<div className={'mb-4'}>
|
|
||||||
<p className={'block font-bold mb-2'}>Period To</p>
|
|
||||||
<p>{archival_items?.period_to}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<p className={'block font-bold mb-2'}>Tags</p>
|
<p className={'block font-bold mb-2'}>Tags</p>
|
||||||
<CardBox
|
<CardBox
|
||||||
|
|||||||
@ -30,7 +30,7 @@ const Dashboard = () => {
|
|||||||
|
|
||||||
const [users, setUsers] = React.useState(loadingMessage);
|
const [users, setUsers] = React.useState(loadingMessage);
|
||||||
const [archival_items, setArchival_items] = React.useState(loadingMessage);
|
const [archival_items, setArchival_items] = React.useState(loadingMessage);
|
||||||
const [galleries, setGalleries] = React.useState(loadingMessage);
|
const [periods, setPeriods] = React.useState(loadingMessage);
|
||||||
const [tags, setTags] = React.useState(loadingMessage);
|
const [tags, setTags] = React.useState(loadingMessage);
|
||||||
const [roles, setRoles] = React.useState(loadingMessage);
|
const [roles, setRoles] = React.useState(loadingMessage);
|
||||||
const [permissions, setPermissions] = React.useState(loadingMessage);
|
const [permissions, setPermissions] = React.useState(loadingMessage);
|
||||||
@ -47,7 +47,7 @@ const Dashboard = () => {
|
|||||||
const entities = [
|
const entities = [
|
||||||
'users',
|
'users',
|
||||||
'archival_items',
|
'archival_items',
|
||||||
'galleries',
|
'periods',
|
||||||
'tags',
|
'tags',
|
||||||
'roles',
|
'roles',
|
||||||
'permissions',
|
'permissions',
|
||||||
@ -55,7 +55,7 @@ const Dashboard = () => {
|
|||||||
const fns = [
|
const fns = [
|
||||||
setUsers,
|
setUsers,
|
||||||
setArchival_items,
|
setArchival_items,
|
||||||
setGalleries,
|
setPeriods,
|
||||||
setTags,
|
setTags,
|
||||||
setRoles,
|
setRoles,
|
||||||
setPermissions,
|
setPermissions,
|
||||||
@ -235,8 +235,8 @@ const Dashboard = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{hasPermission(currentUser, 'READ_GALLERIES') && (
|
{hasPermission(currentUser, 'READ_PERIODS') && (
|
||||||
<Link href={'/galleries/galleries-list'}>
|
<Link href={'/periods/periods-list'}>
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
corners !== 'rounded-full' ? corners : 'rounded-3xl'
|
||||||
@ -245,10 +245,10 @@ const Dashboard = () => {
|
|||||||
<div className='flex justify-between align-center'>
|
<div className='flex justify-between align-center'>
|
||||||
<div>
|
<div>
|
||||||
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
<div className='text-lg leading-tight text-gray-500 dark:text-gray-400'>
|
||||||
Galleries
|
Periods
|
||||||
</div>
|
</div>
|
||||||
<div className='text-3xl leading-tight font-semibold'>
|
<div className='text-3xl leading-tight font-semibold'>
|
||||||
{galleries}
|
{periods}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -25,14 +25,14 @@ import { SelectFieldMany } from '../../components/SelectFieldMany';
|
|||||||
import { SwitchField } from '../../components/SwitchField';
|
import { SwitchField } from '../../components/SwitchField';
|
||||||
import { RichTextField } from '../../components/RichTextField';
|
import { RichTextField } from '../../components/RichTextField';
|
||||||
|
|
||||||
import { update, fetch } from '../../stores/galleries/galleriesSlice';
|
import { update, fetch } from '../../stores/periods/periodsSlice';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { saveFile } from '../../helpers/fileSaver';
|
import { saveFile } from '../../helpers/fileSaver';
|
||||||
import dataFormatter from '../../helpers/dataFormatter';
|
import dataFormatter from '../../helpers/dataFormatter';
|
||||||
import ImageField from '../../components/ImageField';
|
import ImageField from '../../components/ImageField';
|
||||||
|
|
||||||
const EditGalleries = () => {
|
const EditPeriods = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const initVals = {
|
const initVals = {
|
||||||
@ -40,50 +40,50 @@ const EditGalleries = () => {
|
|||||||
|
|
||||||
archival_items: [],
|
archival_items: [],
|
||||||
|
|
||||||
background_image: [],
|
period_from: new Date(),
|
||||||
|
|
||||||
|
period_to: new Date(),
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
const { galleries } = useAppSelector((state) => state.galleries);
|
const { periods } = useAppSelector((state) => state.periods);
|
||||||
|
|
||||||
const { galleriesId } = router.query;
|
const { periodsId } = router.query;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetch({ id: galleriesId }));
|
dispatch(fetch({ id: periodsId }));
|
||||||
}, [galleriesId]);
|
}, [periodsId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof galleries === 'object') {
|
if (typeof periods === 'object') {
|
||||||
setInitialValues(galleries);
|
setInitialValues(periods);
|
||||||
}
|
}
|
||||||
}, [galleries]);
|
}, [periods]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof galleries === 'object') {
|
if (typeof periods === 'object') {
|
||||||
const newInitialVal = { ...initVals };
|
const newInitialVal = { ...initVals };
|
||||||
|
|
||||||
Object.keys(initVals).forEach(
|
Object.keys(initVals).forEach((el) => (newInitialVal[el] = periods[el]));
|
||||||
(el) => (newInitialVal[el] = galleries[el]),
|
|
||||||
);
|
|
||||||
|
|
||||||
setInitialValues(newInitialVal);
|
setInitialValues(newInitialVal);
|
||||||
}
|
}
|
||||||
}, [galleries]);
|
}, [periods]);
|
||||||
|
|
||||||
const handleSubmit = async (data) => {
|
const handleSubmit = async (data) => {
|
||||||
await dispatch(update({ id: galleriesId, data }));
|
await dispatch(update({ id: periodsId, data }));
|
||||||
await router.push('/galleries/galleries-list');
|
await router.push('/periods/periods-list');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('Edit galleries')}</title>
|
<title>{getPageTitle('Edit periods')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton
|
<SectionTitleLineWithButton
|
||||||
icon={mdiChartTimelineVariant}
|
icon={mdiChartTimelineVariant}
|
||||||
title={'Edit galleries'}
|
title={'Edit periods'}
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
{''}
|
{''}
|
||||||
@ -110,20 +110,42 @@ const EditGalleries = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField>
|
<FormField label='Period From'>
|
||||||
<Field
|
<DatePicker
|
||||||
label='Background Image'
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
color='info'
|
showTimeSelect
|
||||||
icon={mdiUpload}
|
selected={
|
||||||
path={'galleries/background_image'}
|
initialValues.period_from
|
||||||
name='background_image'
|
? new Date(
|
||||||
id='background_image'
|
dayjs(initialValues.period_from).format(
|
||||||
schema={{
|
'YYYY-MM-DD hh:mm',
|
||||||
size: undefined,
|
),
|
||||||
formats: undefined,
|
)
|
||||||
}}
|
: null
|
||||||
component={FormImagePicker}
|
}
|
||||||
></Field>
|
onChange={(date) =>
|
||||||
|
setInitialValues({ ...initialValues, period_from: date })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Period To'>
|
||||||
|
<DatePicker
|
||||||
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
|
showTimeSelect
|
||||||
|
selected={
|
||||||
|
initialValues.period_to
|
||||||
|
? new Date(
|
||||||
|
dayjs(initialValues.period_to).format(
|
||||||
|
'YYYY-MM-DD hh:mm',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
onChange={(date) =>
|
||||||
|
setInitialValues({ ...initialValues, period_to: date })
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
@ -135,7 +157,7 @@ const EditGalleries = () => {
|
|||||||
color='danger'
|
color='danger'
|
||||||
outline
|
outline
|
||||||
label='Cancel'
|
label='Cancel'
|
||||||
onClick={() => router.push('/galleries/galleries-list')}
|
onClick={() => router.push('/periods/periods-list')}
|
||||||
/>
|
/>
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</Form>
|
</Form>
|
||||||
@ -146,12 +168,12 @@ const EditGalleries = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
EditGalleries.getLayout = function getLayout(page: ReactElement) {
|
EditPeriods.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'UPDATE_GALLERIES'}>
|
<LayoutAuthenticated permission={'UPDATE_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditGalleries;
|
export default EditPeriods;
|
||||||
@ -25,14 +25,14 @@ import { SelectFieldMany } from '../../components/SelectFieldMany';
|
|||||||
import { SwitchField } from '../../components/SwitchField';
|
import { SwitchField } from '../../components/SwitchField';
|
||||||
import { RichTextField } from '../../components/RichTextField';
|
import { RichTextField } from '../../components/RichTextField';
|
||||||
|
|
||||||
import { update, fetch } from '../../stores/galleries/galleriesSlice';
|
import { update, fetch } from '../../stores/periods/periodsSlice';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { saveFile } from '../../helpers/fileSaver';
|
import { saveFile } from '../../helpers/fileSaver';
|
||||||
import dataFormatter from '../../helpers/dataFormatter';
|
import dataFormatter from '../../helpers/dataFormatter';
|
||||||
import ImageField from '../../components/ImageField';
|
import ImageField from '../../components/ImageField';
|
||||||
|
|
||||||
const EditGalleriesPage = () => {
|
const EditPeriodsPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const initVals = {
|
const initVals = {
|
||||||
@ -40,11 +40,13 @@ const EditGalleriesPage = () => {
|
|||||||
|
|
||||||
archival_items: [],
|
archival_items: [],
|
||||||
|
|
||||||
background_image: [],
|
period_from: new Date(),
|
||||||
|
|
||||||
|
period_to: new Date(),
|
||||||
};
|
};
|
||||||
const [initialValues, setInitialValues] = useState(initVals);
|
const [initialValues, setInitialValues] = useState(initVals);
|
||||||
|
|
||||||
const { galleries } = useAppSelector((state) => state.galleries);
|
const { periods } = useAppSelector((state) => state.periods);
|
||||||
|
|
||||||
const { id } = router.query;
|
const { id } = router.query;
|
||||||
|
|
||||||
@ -53,35 +55,33 @@ const EditGalleriesPage = () => {
|
|||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof galleries === 'object') {
|
if (typeof periods === 'object') {
|
||||||
setInitialValues(galleries);
|
setInitialValues(periods);
|
||||||
}
|
}
|
||||||
}, [galleries]);
|
}, [periods]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof galleries === 'object') {
|
if (typeof periods === 'object') {
|
||||||
const newInitialVal = { ...initVals };
|
const newInitialVal = { ...initVals };
|
||||||
Object.keys(initVals).forEach(
|
Object.keys(initVals).forEach((el) => (newInitialVal[el] = periods[el]));
|
||||||
(el) => (newInitialVal[el] = galleries[el]),
|
|
||||||
);
|
|
||||||
setInitialValues(newInitialVal);
|
setInitialValues(newInitialVal);
|
||||||
}
|
}
|
||||||
}, [galleries]);
|
}, [periods]);
|
||||||
|
|
||||||
const handleSubmit = async (data) => {
|
const handleSubmit = async (data) => {
|
||||||
await dispatch(update({ id: id, data }));
|
await dispatch(update({ id: id, data }));
|
||||||
await router.push('/galleries/galleries-list');
|
await router.push('/periods/periods-list');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('Edit galleries')}</title>
|
<title>{getPageTitle('Edit periods')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton
|
<SectionTitleLineWithButton
|
||||||
icon={mdiChartTimelineVariant}
|
icon={mdiChartTimelineVariant}
|
||||||
title={'Edit galleries'}
|
title={'Edit periods'}
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
{''}
|
{''}
|
||||||
@ -108,20 +108,42 @@ const EditGalleriesPage = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField>
|
<FormField label='Period From'>
|
||||||
<Field
|
<DatePicker
|
||||||
label='Background Image'
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
color='info'
|
showTimeSelect
|
||||||
icon={mdiUpload}
|
selected={
|
||||||
path={'galleries/background_image'}
|
initialValues.period_from
|
||||||
name='background_image'
|
? new Date(
|
||||||
id='background_image'
|
dayjs(initialValues.period_from).format(
|
||||||
schema={{
|
'YYYY-MM-DD hh:mm',
|
||||||
size: undefined,
|
),
|
||||||
formats: undefined,
|
)
|
||||||
}}
|
: null
|
||||||
component={FormImagePicker}
|
}
|
||||||
></Field>
|
onChange={(date) =>
|
||||||
|
setInitialValues({ ...initialValues, period_from: date })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Period To'>
|
||||||
|
<DatePicker
|
||||||
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
|
showTimeSelect
|
||||||
|
selected={
|
||||||
|
initialValues.period_to
|
||||||
|
? new Date(
|
||||||
|
dayjs(initialValues.period_to).format(
|
||||||
|
'YYYY-MM-DD hh:mm',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
onChange={(date) =>
|
||||||
|
setInitialValues({ ...initialValues, period_to: date })
|
||||||
|
}
|
||||||
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
@ -133,7 +155,7 @@ const EditGalleriesPage = () => {
|
|||||||
color='danger'
|
color='danger'
|
||||||
outline
|
outline
|
||||||
label='Cancel'
|
label='Cancel'
|
||||||
onClick={() => router.push('/galleries/galleries-list')}
|
onClick={() => router.push('/periods/periods-list')}
|
||||||
/>
|
/>
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</Form>
|
</Form>
|
||||||
@ -144,12 +166,12 @@ const EditGalleriesPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
EditGalleriesPage.getLayout = function getLayout(page: ReactElement) {
|
EditPeriodsPage.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'UPDATE_GALLERIES'}>
|
<LayoutAuthenticated permission={'UPDATE_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditGalleriesPage;
|
export default EditPeriodsPage;
|
||||||
@ -7,18 +7,18 @@ import LayoutAuthenticated from '../../layouts/Authenticated';
|
|||||||
import SectionMain from '../../components/SectionMain';
|
import SectionMain from '../../components/SectionMain';
|
||||||
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
|
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
|
||||||
import { getPageTitle } from '../../config';
|
import { getPageTitle } from '../../config';
|
||||||
import TableGalleries from '../../components/Galleries/TableGalleries';
|
import TablePeriods from '../../components/Periods/TablePeriods';
|
||||||
import BaseButton from '../../components/BaseButton';
|
import BaseButton from '../../components/BaseButton';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import CardBoxModal from '../../components/CardBoxModal';
|
import CardBoxModal from '../../components/CardBoxModal';
|
||||||
import DragDropFilePicker from '../../components/DragDropFilePicker';
|
import DragDropFilePicker from '../../components/DragDropFilePicker';
|
||||||
import { setRefetch, uploadCsv } from '../../stores/galleries/galleriesSlice';
|
import { setRefetch, uploadCsv } from '../../stores/periods/periodsSlice';
|
||||||
|
|
||||||
import { hasPermission } from '../../helpers/userPermissions';
|
import { hasPermission } from '../../helpers/userPermissions';
|
||||||
|
|
||||||
const GalleriesTablesPage = () => {
|
const PeriodsTablesPage = () => {
|
||||||
const [filterItems, setFilterItems] = useState([]);
|
const [filterItems, setFilterItems] = useState([]);
|
||||||
const [csvFile, setCsvFile] = useState<File | null>(null);
|
const [csvFile, setCsvFile] = useState<File | null>(null);
|
||||||
const [isModalActive, setIsModalActive] = useState(false);
|
const [isModalActive, setIsModalActive] = useState(false);
|
||||||
@ -31,11 +31,14 @@ const GalleriesTablesPage = () => {
|
|||||||
const [filters] = useState([
|
const [filters] = useState([
|
||||||
{ label: 'Name', title: 'name' },
|
{ label: 'Name', title: 'name' },
|
||||||
|
|
||||||
|
{ label: 'Period From', title: 'period_from', date: 'true' },
|
||||||
|
{ label: 'Period To', title: 'period_to', date: 'true' },
|
||||||
|
|
||||||
{ label: 'Archival Items', title: 'archival_items' },
|
{ label: 'Archival Items', title: 'archival_items' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
currentUser && hasPermission(currentUser, 'CREATE_GALLERIES');
|
currentUser && hasPermission(currentUser, 'CREATE_PERIODS');
|
||||||
|
|
||||||
const addFilter = () => {
|
const addFilter = () => {
|
||||||
const newItem = {
|
const newItem = {
|
||||||
@ -51,9 +54,9 @@ const GalleriesTablesPage = () => {
|
|||||||
setFilterItems([...filterItems, newItem]);
|
setFilterItems([...filterItems, newItem]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGalleriesCSV = async () => {
|
const getPeriodsCSV = async () => {
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
url: '/galleries?filetype=csv',
|
url: '/periods?filetype=csv',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
});
|
});
|
||||||
@ -61,7 +64,7 @@ const GalleriesTablesPage = () => {
|
|||||||
const blob = new Blob([response.data], { type: type });
|
const blob = new Blob([response.data], { type: type });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
link.download = 'galleriesCSV.csv';
|
link.download = 'periodsCSV.csv';
|
||||||
link.click();
|
link.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,12 +84,12 @@ const GalleriesTablesPage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('Galleries')}</title>
|
<title>{getPageTitle('Periods')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton
|
<SectionTitleLineWithButton
|
||||||
icon={mdiChartTimelineVariant}
|
icon={mdiChartTimelineVariant}
|
||||||
title='Galleries'
|
title='Periods'
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
{''}
|
{''}
|
||||||
@ -95,7 +98,7 @@ const GalleriesTablesPage = () => {
|
|||||||
{hasCreatePermission && (
|
{hasCreatePermission && (
|
||||||
<BaseButton
|
<BaseButton
|
||||||
className={'mr-3'}
|
className={'mr-3'}
|
||||||
href={'/galleries/galleries-new'}
|
href={'/periods/periods-new'}
|
||||||
color='info'
|
color='info'
|
||||||
label='New Item'
|
label='New Item'
|
||||||
/>
|
/>
|
||||||
@ -111,7 +114,7 @@ const GalleriesTablesPage = () => {
|
|||||||
className={'mr-3'}
|
className={'mr-3'}
|
||||||
color='info'
|
color='info'
|
||||||
label='Download CSV'
|
label='Download CSV'
|
||||||
onClick={getGalleriesCSV}
|
onClick={getPeriodsCSV}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{hasCreatePermission && (
|
{hasCreatePermission && (
|
||||||
@ -128,7 +131,7 @@ const GalleriesTablesPage = () => {
|
|||||||
</CardBox>
|
</CardBox>
|
||||||
|
|
||||||
<CardBox className='mb-6' hasTable>
|
<CardBox className='mb-6' hasTable>
|
||||||
<TableGalleries
|
<TablePeriods
|
||||||
filterItems={filterItems}
|
filterItems={filterItems}
|
||||||
setFilterItems={setFilterItems}
|
setFilterItems={setFilterItems}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
@ -155,12 +158,12 @@ const GalleriesTablesPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
GalleriesTablesPage.getLayout = function getLayout(page: ReactElement) {
|
PeriodsTablesPage.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'READ_GALLERIES'}>
|
<LayoutAuthenticated permission={'READ_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GalleriesTablesPage;
|
export default PeriodsTablesPage;
|
||||||
@ -27,7 +27,7 @@ import { SelectField } from '../../components/SelectField';
|
|||||||
import { SelectFieldMany } from '../../components/SelectFieldMany';
|
import { SelectFieldMany } from '../../components/SelectFieldMany';
|
||||||
import { RichTextField } from '../../components/RichTextField';
|
import { RichTextField } from '../../components/RichTextField';
|
||||||
|
|
||||||
import { create } from '../../stores/galleries/galleriesSlice';
|
import { create } from '../../stores/periods/periodsSlice';
|
||||||
import { useAppDispatch } from '../../stores/hooks';
|
import { useAppDispatch } from '../../stores/hooks';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -37,16 +37,18 @@ const initialValues = {
|
|||||||
|
|
||||||
archival_items: [],
|
archival_items: [],
|
||||||
|
|
||||||
background_image: [],
|
period_from: '',
|
||||||
|
|
||||||
|
period_to: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const GalleriesNew = () => {
|
const PeriodsNew = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const handleSubmit = async (data) => {
|
const handleSubmit = async (data) => {
|
||||||
await dispatch(create(data));
|
await dispatch(create(data));
|
||||||
await router.push('/galleries/galleries-list');
|
await router.push('/periods/periods-list');
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -81,20 +83,20 @@ const GalleriesNew = () => {
|
|||||||
></Field>
|
></Field>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<FormField>
|
<FormField label='Period From'>
|
||||||
<Field
|
<Field
|
||||||
label='Background Image'
|
type='datetime-local'
|
||||||
color='info'
|
name='period_from'
|
||||||
icon={mdiUpload}
|
placeholder='Period From'
|
||||||
path={'galleries/background_image'}
|
/>
|
||||||
name='background_image'
|
</FormField>
|
||||||
id='background_image'
|
|
||||||
schema={{
|
<FormField label='Period To'>
|
||||||
size: undefined,
|
<Field
|
||||||
formats: undefined,
|
type='datetime-local'
|
||||||
}}
|
name='period_to'
|
||||||
component={FormImagePicker}
|
placeholder='Period To'
|
||||||
></Field>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
@ -106,7 +108,7 @@ const GalleriesNew = () => {
|
|||||||
color='danger'
|
color='danger'
|
||||||
outline
|
outline
|
||||||
label='Cancel'
|
label='Cancel'
|
||||||
onClick={() => router.push('/galleries/galleries-list')}
|
onClick={() => router.push('/periods/periods-list')}
|
||||||
/>
|
/>
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</Form>
|
</Form>
|
||||||
@ -117,12 +119,12 @@ const GalleriesNew = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
GalleriesNew.getLayout = function getLayout(page: ReactElement) {
|
PeriodsNew.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'CREATE_GALLERIES'}>
|
<LayoutAuthenticated permission={'CREATE_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GalleriesNew;
|
export default PeriodsNew;
|
||||||
@ -7,18 +7,18 @@ import LayoutAuthenticated from '../../layouts/Authenticated';
|
|||||||
import SectionMain from '../../components/SectionMain';
|
import SectionMain from '../../components/SectionMain';
|
||||||
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
|
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
|
||||||
import { getPageTitle } from '../../config';
|
import { getPageTitle } from '../../config';
|
||||||
import TableGalleries from '../../components/Galleries/TableGalleries';
|
import TablePeriods from '../../components/Periods/TablePeriods';
|
||||||
import BaseButton from '../../components/BaseButton';
|
import BaseButton from '../../components/BaseButton';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import CardBoxModal from '../../components/CardBoxModal';
|
import CardBoxModal from '../../components/CardBoxModal';
|
||||||
import DragDropFilePicker from '../../components/DragDropFilePicker';
|
import DragDropFilePicker from '../../components/DragDropFilePicker';
|
||||||
import { setRefetch, uploadCsv } from '../../stores/galleries/galleriesSlice';
|
import { setRefetch, uploadCsv } from '../../stores/periods/periodsSlice';
|
||||||
|
|
||||||
import { hasPermission } from '../../helpers/userPermissions';
|
import { hasPermission } from '../../helpers/userPermissions';
|
||||||
|
|
||||||
const GalleriesTablesPage = () => {
|
const PeriodsTablesPage = () => {
|
||||||
const [filterItems, setFilterItems] = useState([]);
|
const [filterItems, setFilterItems] = useState([]);
|
||||||
const [csvFile, setCsvFile] = useState<File | null>(null);
|
const [csvFile, setCsvFile] = useState<File | null>(null);
|
||||||
const [isModalActive, setIsModalActive] = useState(false);
|
const [isModalActive, setIsModalActive] = useState(false);
|
||||||
@ -31,11 +31,14 @@ const GalleriesTablesPage = () => {
|
|||||||
const [filters] = useState([
|
const [filters] = useState([
|
||||||
{ label: 'Name', title: 'name' },
|
{ label: 'Name', title: 'name' },
|
||||||
|
|
||||||
|
{ label: 'Period From', title: 'period_from', date: 'true' },
|
||||||
|
{ label: 'Period To', title: 'period_to', date: 'true' },
|
||||||
|
|
||||||
{ label: 'Archival Items', title: 'archival_items' },
|
{ label: 'Archival Items', title: 'archival_items' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const hasCreatePermission =
|
const hasCreatePermission =
|
||||||
currentUser && hasPermission(currentUser, 'CREATE_GALLERIES');
|
currentUser && hasPermission(currentUser, 'CREATE_PERIODS');
|
||||||
|
|
||||||
const addFilter = () => {
|
const addFilter = () => {
|
||||||
const newItem = {
|
const newItem = {
|
||||||
@ -51,9 +54,9 @@ const GalleriesTablesPage = () => {
|
|||||||
setFilterItems([...filterItems, newItem]);
|
setFilterItems([...filterItems, newItem]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGalleriesCSV = async () => {
|
const getPeriodsCSV = async () => {
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
url: '/galleries?filetype=csv',
|
url: '/periods?filetype=csv',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
});
|
});
|
||||||
@ -61,7 +64,7 @@ const GalleriesTablesPage = () => {
|
|||||||
const blob = new Blob([response.data], { type: type });
|
const blob = new Blob([response.data], { type: type });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
link.download = 'galleriesCSV.csv';
|
link.download = 'periodsCSV.csv';
|
||||||
link.click();
|
link.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,12 +84,12 @@ const GalleriesTablesPage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('Galleries')}</title>
|
<title>{getPageTitle('Periods')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton
|
<SectionTitleLineWithButton
|
||||||
icon={mdiChartTimelineVariant}
|
icon={mdiChartTimelineVariant}
|
||||||
title='Galleries'
|
title='Periods'
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
{''}
|
{''}
|
||||||
@ -95,7 +98,7 @@ const GalleriesTablesPage = () => {
|
|||||||
{hasCreatePermission && (
|
{hasCreatePermission && (
|
||||||
<BaseButton
|
<BaseButton
|
||||||
className={'mr-3'}
|
className={'mr-3'}
|
||||||
href={'/galleries/galleries-new'}
|
href={'/periods/periods-new'}
|
||||||
color='info'
|
color='info'
|
||||||
label='New Item'
|
label='New Item'
|
||||||
/>
|
/>
|
||||||
@ -111,7 +114,7 @@ const GalleriesTablesPage = () => {
|
|||||||
className={'mr-3'}
|
className={'mr-3'}
|
||||||
color='info'
|
color='info'
|
||||||
label='Download CSV'
|
label='Download CSV'
|
||||||
onClick={getGalleriesCSV}
|
onClick={getPeriodsCSV}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{hasCreatePermission && (
|
{hasCreatePermission && (
|
||||||
@ -127,7 +130,7 @@ const GalleriesTablesPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
<CardBox className='mb-6' hasTable>
|
<CardBox className='mb-6' hasTable>
|
||||||
<TableGalleries
|
<TablePeriods
|
||||||
filterItems={filterItems}
|
filterItems={filterItems}
|
||||||
setFilterItems={setFilterItems}
|
setFilterItems={setFilterItems}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
@ -154,12 +157,12 @@ const GalleriesTablesPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
GalleriesTablesPage.getLayout = function getLayout(page: ReactElement) {
|
PeriodsTablesPage.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'READ_GALLERIES'}>
|
<LayoutAuthenticated permission={'READ_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GalleriesTablesPage;
|
export default PeriodsTablesPage;
|
||||||
@ -5,7 +5,7 @@ import 'react-datepicker/dist/react-datepicker.css';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { fetch } from '../../stores/galleries/galleriesSlice';
|
import { fetch } from '../../stores/periods/periodsSlice';
|
||||||
import { saveFile } from '../../helpers/fileSaver';
|
import { saveFile } from '../../helpers/fileSaver';
|
||||||
import dataFormatter from '../../helpers/dataFormatter';
|
import dataFormatter from '../../helpers/dataFormatter';
|
||||||
import ImageField from '../../components/ImageField';
|
import ImageField from '../../components/ImageField';
|
||||||
@ -20,10 +20,10 @@ import { mdiChartTimelineVariant } from '@mdi/js';
|
|||||||
import { SwitchField } from '../../components/SwitchField';
|
import { SwitchField } from '../../components/SwitchField';
|
||||||
import FormField from '../../components/FormField';
|
import FormField from '../../components/FormField';
|
||||||
|
|
||||||
const GalleriesView = () => {
|
const PeriodsView = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { galleries } = useAppSelector((state) => state.galleries);
|
const { periods } = useAppSelector((state) => state.periods);
|
||||||
|
|
||||||
const { id } = router.query;
|
const { id } = router.query;
|
||||||
|
|
||||||
@ -39,24 +39,24 @@ const GalleriesView = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('View galleries')}</title>
|
<title>{getPageTitle('View periods')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton
|
<SectionTitleLineWithButton
|
||||||
icon={mdiChartTimelineVariant}
|
icon={mdiChartTimelineVariant}
|
||||||
title={removeLastCharacter('View galleries')}
|
title={removeLastCharacter('View periods')}
|
||||||
main
|
main
|
||||||
>
|
>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
color='info'
|
color='info'
|
||||||
label='Edit'
|
label='Edit'
|
||||||
href={`/galleries/galleries-edit/?id=${id}`}
|
href={`/periods/periods-edit/?id=${id}`}
|
||||||
/>
|
/>
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
<CardBox>
|
<CardBox>
|
||||||
<div className={'mb-4'}>
|
<div className={'mb-4'}>
|
||||||
<p className={'block font-bold mb-2'}>Name</p>
|
<p className={'block font-bold mb-2'}>Name</p>
|
||||||
<p>{galleries?.name}</p>
|
<p>{periods?.name}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
@ -74,16 +74,12 @@ const GalleriesView = () => {
|
|||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
|
|
||||||
<th>Is Published</th>
|
<th>Is Published</th>
|
||||||
|
|
||||||
<th>Period From</th>
|
|
||||||
|
|
||||||
<th>Period To</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{galleries.archival_items &&
|
{periods.archival_items &&
|
||||||
Array.isArray(galleries.archival_items) &&
|
Array.isArray(periods.archival_items) &&
|
||||||
galleries.archival_items.map((item: any) => (
|
periods.archival_items.map((item: any) => (
|
||||||
<tr
|
<tr
|
||||||
key={item.id}
|
key={item.id}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@ -99,42 +95,61 @@ const GalleriesView = () => {
|
|||||||
<td data-label='isPublished'>
|
<td data-label='isPublished'>
|
||||||
{dataFormatter.booleanFormatter(item.isPublished)}
|
{dataFormatter.booleanFormatter(item.isPublished)}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td data-label='period_from'>
|
|
||||||
{dataFormatter.dateFormatter(item.period_from)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td data-label='period_to'>{item.period_to}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{!galleries?.archival_items?.length && (
|
{!periods?.archival_items?.length && (
|
||||||
<div className={'text-center py-4'}>No data</div>
|
<div className={'text-center py-4'}>No data</div>
|
||||||
)}
|
)}
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
<div className={'mb-4'}>
|
<FormField label='Period From'>
|
||||||
<p className={'block font-bold mb-2'}>Background Image</p>
|
{periods.period_from ? (
|
||||||
{galleries?.background_image?.length ? (
|
<DatePicker
|
||||||
<ImageField
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
name={'background_image'}
|
showTimeSelect
|
||||||
image={galleries?.background_image}
|
selected={
|
||||||
className='w-20 h-20'
|
periods.period_from
|
||||||
|
? new Date(
|
||||||
|
dayjs(periods.period_from).format('YYYY-MM-DD hh:mm'),
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<p>No Background Image</p>
|
<p>No Period From</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</FormField>
|
||||||
|
|
||||||
|
<FormField label='Period To'>
|
||||||
|
{periods.period_to ? (
|
||||||
|
<DatePicker
|
||||||
|
dateFormat='yyyy-MM-dd hh:mm'
|
||||||
|
showTimeSelect
|
||||||
|
selected={
|
||||||
|
periods.period_to
|
||||||
|
? new Date(
|
||||||
|
dayjs(periods.period_to).format('YYYY-MM-DD hh:mm'),
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<p>No Period To</p>
|
||||||
|
)}
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
|
|
||||||
<BaseButton
|
<BaseButton
|
||||||
color='info'
|
color='info'
|
||||||
label='Back'
|
label='Back'
|
||||||
onClick={() => router.push('/galleries/galleries-list')}
|
onClick={() => router.push('/periods/periods-list')}
|
||||||
/>
|
/>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</SectionMain>
|
</SectionMain>
|
||||||
@ -142,12 +157,12 @@ const GalleriesView = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
GalleriesView.getLayout = function getLayout(page: ReactElement) {
|
PeriodsView.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'READ_GALLERIES'}>
|
<LayoutAuthenticated permission={'READ_PERIODS'}>
|
||||||
{page}
|
{page}
|
||||||
</LayoutAuthenticated>
|
</LayoutAuthenticated>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GalleriesView;
|
export default PeriodsView;
|
||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from '../../helpers/notifyStateHandler';
|
} from '../../helpers/notifyStateHandler';
|
||||||
|
|
||||||
interface MainState {
|
interface MainState {
|
||||||
galleries: any;
|
periods: any;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
count: number;
|
count: number;
|
||||||
refetch: boolean;
|
refetch: boolean;
|
||||||
@ -20,7 +20,7 @@ interface MainState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initialState: MainState = {
|
const initialState: MainState = {
|
||||||
galleries: [],
|
periods: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
count: 0,
|
count: 0,
|
||||||
refetch: false,
|
refetch: false,
|
||||||
@ -32,19 +32,19 @@ const initialState: MainState = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetch = createAsyncThunk('galleries/fetch', async (data: any) => {
|
export const fetch = createAsyncThunk('periods/fetch', async (data: any) => {
|
||||||
const { id, query } = data;
|
const { id, query } = data;
|
||||||
const result = await axios.get(`galleries${query || (id ? `/${id}` : '')}`);
|
const result = await axios.get(`periods${query || (id ? `/${id}` : '')}`);
|
||||||
return id
|
return id
|
||||||
? result.data
|
? result.data
|
||||||
: { rows: result.data.rows, count: result.data.count };
|
: { rows: result.data.rows, count: result.data.count };
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deleteItemsByIds = createAsyncThunk(
|
export const deleteItemsByIds = createAsyncThunk(
|
||||||
'galleries/deleteByIds',
|
'periods/deleteByIds',
|
||||||
async (data: any, { rejectWithValue }) => {
|
async (data: any, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
await axios.post('galleries/deleteByIds', { data });
|
await axios.post('periods/deleteByIds', { data });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!error.response) {
|
if (!error.response) {
|
||||||
throw error;
|
throw error;
|
||||||
@ -56,10 +56,10 @@ export const deleteItemsByIds = createAsyncThunk(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const deleteItem = createAsyncThunk(
|
export const deleteItem = createAsyncThunk(
|
||||||
'galleries/deleteGalleries',
|
'periods/deletePeriods',
|
||||||
async (id: string, { rejectWithValue }) => {
|
async (id: string, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
await axios.delete(`galleries/${id}`);
|
await axios.delete(`periods/${id}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!error.response) {
|
if (!error.response) {
|
||||||
throw error;
|
throw error;
|
||||||
@ -71,10 +71,10 @@ export const deleteItem = createAsyncThunk(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const create = createAsyncThunk(
|
export const create = createAsyncThunk(
|
||||||
'galleries/createGalleries',
|
'periods/createPeriods',
|
||||||
async (data: any, { rejectWithValue }) => {
|
async (data: any, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const result = await axios.post('galleries', { data });
|
const result = await axios.post('periods', { data });
|
||||||
return result.data;
|
return result.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!error.response) {
|
if (!error.response) {
|
||||||
@ -87,14 +87,14 @@ export const create = createAsyncThunk(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const uploadCsv = createAsyncThunk(
|
export const uploadCsv = createAsyncThunk(
|
||||||
'galleries/uploadCsv',
|
'periods/uploadCsv',
|
||||||
async (file: File, { rejectWithValue }) => {
|
async (file: File, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append('file', file);
|
data.append('file', file);
|
||||||
data.append('filename', file.name);
|
data.append('filename', file.name);
|
||||||
|
|
||||||
const result = await axios.post('galleries/bulk-import', data, {
|
const result = await axios.post('periods/bulk-import', data, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
},
|
},
|
||||||
@ -112,10 +112,10 @@ export const uploadCsv = createAsyncThunk(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const update = createAsyncThunk(
|
export const update = createAsyncThunk(
|
||||||
'galleries/updateGalleries',
|
'periods/updatePeriods',
|
||||||
async (payload: any, { rejectWithValue }) => {
|
async (payload: any, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const result = await axios.put(`galleries/${payload.id}`, {
|
const result = await axios.put(`periods/${payload.id}`, {
|
||||||
id: payload.id,
|
id: payload.id,
|
||||||
data: payload.data,
|
data: payload.data,
|
||||||
});
|
});
|
||||||
@ -130,8 +130,8 @@ export const update = createAsyncThunk(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const galleriesSlice = createSlice({
|
export const periodsSlice = createSlice({
|
||||||
name: 'galleries',
|
name: 'periods',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setRefetch: (state, action: PayloadAction<boolean>) => {
|
setRefetch: (state, action: PayloadAction<boolean>) => {
|
||||||
@ -150,10 +150,10 @@ export const galleriesSlice = createSlice({
|
|||||||
|
|
||||||
builder.addCase(fetch.fulfilled, (state, action) => {
|
builder.addCase(fetch.fulfilled, (state, action) => {
|
||||||
if (action.payload.rows && action.payload.count >= 0) {
|
if (action.payload.rows && action.payload.count >= 0) {
|
||||||
state.galleries = action.payload.rows;
|
state.periods = action.payload.rows;
|
||||||
state.count = action.payload.count;
|
state.count = action.payload.count;
|
||||||
} else {
|
} else {
|
||||||
state.galleries = action.payload;
|
state.periods = action.payload;
|
||||||
}
|
}
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
});
|
});
|
||||||
@ -165,7 +165,7 @@ export const galleriesSlice = createSlice({
|
|||||||
|
|
||||||
builder.addCase(deleteItemsByIds.fulfilled, (state) => {
|
builder.addCase(deleteItemsByIds.fulfilled, (state) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
fulfilledNotify(state, 'Galleries has been deleted');
|
fulfilledNotify(state, 'Periods has been deleted');
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.addCase(deleteItemsByIds.rejected, (state, action) => {
|
builder.addCase(deleteItemsByIds.rejected, (state, action) => {
|
||||||
@ -180,7 +180,7 @@ export const galleriesSlice = createSlice({
|
|||||||
|
|
||||||
builder.addCase(deleteItem.fulfilled, (state) => {
|
builder.addCase(deleteItem.fulfilled, (state) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
fulfilledNotify(state, `${'Galleries'.slice(0, -1)} has been deleted`);
|
fulfilledNotify(state, `${'Periods'.slice(0, -1)} has been deleted`);
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.addCase(deleteItem.rejected, (state, action) => {
|
builder.addCase(deleteItem.rejected, (state, action) => {
|
||||||
@ -199,7 +199,7 @@ export const galleriesSlice = createSlice({
|
|||||||
|
|
||||||
builder.addCase(create.fulfilled, (state) => {
|
builder.addCase(create.fulfilled, (state) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
fulfilledNotify(state, `${'Galleries'.slice(0, -1)} has been created`);
|
fulfilledNotify(state, `${'Periods'.slice(0, -1)} has been created`);
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.addCase(update.pending, (state) => {
|
builder.addCase(update.pending, (state) => {
|
||||||
@ -208,7 +208,7 @@ export const galleriesSlice = createSlice({
|
|||||||
});
|
});
|
||||||
builder.addCase(update.fulfilled, (state) => {
|
builder.addCase(update.fulfilled, (state) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
fulfilledNotify(state, `${'Galleries'.slice(0, -1)} has been updated`);
|
fulfilledNotify(state, `${'Periods'.slice(0, -1)} has been updated`);
|
||||||
});
|
});
|
||||||
builder.addCase(update.rejected, (state, action) => {
|
builder.addCase(update.rejected, (state, action) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@ -221,7 +221,7 @@ export const galleriesSlice = createSlice({
|
|||||||
});
|
});
|
||||||
builder.addCase(uploadCsv.fulfilled, (state) => {
|
builder.addCase(uploadCsv.fulfilled, (state) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
fulfilledNotify(state, 'Galleries has been uploaded');
|
fulfilledNotify(state, 'Periods has been uploaded');
|
||||||
});
|
});
|
||||||
builder.addCase(uploadCsv.rejected, (state, action) => {
|
builder.addCase(uploadCsv.rejected, (state, action) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@ -231,6 +231,6 @@ export const galleriesSlice = createSlice({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Action creators are generated for each case reducer function
|
// Action creators are generated for each case reducer function
|
||||||
export const { setRefetch } = galleriesSlice.actions;
|
export const { setRefetch } = periodsSlice.actions;
|
||||||
|
|
||||||
export default galleriesSlice.reducer;
|
export default periodsSlice.reducer;
|
||||||
@ -6,7 +6,7 @@ import openAiSlice from './openAiSlice';
|
|||||||
|
|
||||||
import usersSlice from './users/usersSlice';
|
import usersSlice from './users/usersSlice';
|
||||||
import archival_itemsSlice from './archival_items/archival_itemsSlice';
|
import archival_itemsSlice from './archival_items/archival_itemsSlice';
|
||||||
import galleriesSlice from './galleries/galleriesSlice';
|
import periodsSlice from './periods/periodsSlice';
|
||||||
import tagsSlice from './tags/tagsSlice';
|
import tagsSlice from './tags/tagsSlice';
|
||||||
import rolesSlice from './roles/rolesSlice';
|
import rolesSlice from './roles/rolesSlice';
|
||||||
import permissionsSlice from './permissions/permissionsSlice';
|
import permissionsSlice from './permissions/permissionsSlice';
|
||||||
@ -20,7 +20,7 @@ export const store = configureStore({
|
|||||||
|
|
||||||
users: usersSlice,
|
users: usersSlice,
|
||||||
archival_items: archival_itemsSlice,
|
archival_items: archival_itemsSlice,
|
||||||
galleries: galleriesSlice,
|
periods: periodsSlice,
|
||||||
tags: tagsSlice,
|
tags: tagsSlice,
|
||||||
roles: rolesSlice,
|
roles: rolesSlice,
|
||||||
permissions: permissionsSlice,
|
permissions: permissionsSlice,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user