Commit - 20251017-135209538

This commit is contained in:
Flatlogic Bot 2025-10-17 13:52:28 +00:00
parent 0a2bfbdca7
commit 4591f2d5b9
24 changed files with 251 additions and 202 deletions

View File

@ -26,6 +26,10 @@ module.exports = class Archival_itemsDBApi {
{ transaction }, { transaction },
); );
await archival_items.setPeriod(data.period || null, {
transaction,
});
await archival_items.setTags(data.tags || [], { await archival_items.setTags(data.tags || [], {
transaction, transaction,
}); });
@ -108,6 +112,14 @@ module.exports = class Archival_itemsDBApi {
await archival_items.update(updatePayload, { transaction }); await archival_items.update(updatePayload, { transaction });
if (data.period !== undefined) {
await archival_items.setPeriod(
data.period,
{ transaction },
);
}
if (data.tags !== undefined) { if (data.tags !== undefined) {
await archival_items.setTags(data.tags, { transaction }); await archival_items.setTags(data.tags, { transaction });
} }
@ -194,6 +206,10 @@ module.exports = class Archival_itemsDBApi {
transaction, transaction,
}); });
output.period = await archival_items.getPeriod({
transaction,
});
return output; return output;
} }
@ -210,6 +226,32 @@ module.exports = class Archival_itemsDBApi {
const transaction = (options && options.transaction) || undefined; const transaction = (options && options.transaction) || undefined;
let include = [ let include = [
{
model: db.periods,
as: 'period',
where: filter.period
? {
[Op.or]: [
{
id: {
[Op.in]: filter.period
.split('|')
.map((term) => Utils.uuid(term)),
},
},
{
id: {
[Op.or]: filter.period
.split('|')
.map((term) => ({ [Op.iLike]: `%${term}%` })),
},
},
],
}
: {},
},
{ {
model: db.tags, model: db.tags,
as: 'tags', as: 'tags',

View File

@ -25,10 +25,6 @@ module.exports = class PeriodsDBApi {
{ transaction }, { transaction },
); );
await periods.setArchival_items(data.archival_items || [], {
transaction,
});
return periods; return periods;
} }
@ -76,10 +72,6 @@ module.exports = class PeriodsDBApi {
await periods.update(updatePayload, { transaction }); await periods.update(updatePayload, { transaction });
if (data.archival_items !== undefined) {
await periods.setArchival_items(data.archival_items, { transaction });
}
return periods; return periods;
} }
@ -141,7 +133,7 @@ module.exports = class PeriodsDBApi {
const output = periods.get({ plain: true }); const output = periods.get({ plain: true });
output.archival_items = await periods.getArchival_items({ output.archival_items_period = await periods.getArchival_items_period({
transaction, transaction,
}); });
@ -160,13 +152,7 @@ module.exports = class PeriodsDBApi {
const transaction = (options && options.transaction) || undefined; const transaction = (options && options.transaction) || undefined;
let include = [ let include = [];
{
model: db.archival_items,
as: 'archival_items',
required: false,
},
];
if (filter) { if (filter) {
if (filter.id) { if (filter.id) {
@ -238,38 +224,6 @@ module.exports = class PeriodsDBApi {
}; };
} }
if (filter.archival_items) {
const searchTerms = filter.archival_items.split('|');
include = [
{
model: db.archival_items,
as: 'archival_items_filter',
required: searchTerms.length > 0,
where:
searchTerms.length > 0
? {
[Op.or]: [
{
id: {
[Op.in]: searchTerms.map((term) => Utils.uuid(term)),
},
},
{
id: {
[Op.or]: searchTerms.map((term) => ({
[Op.iLike]: `%${term}%`,
})),
},
},
],
}
: undefined,
},
...include,
];
}
if (filter.createdAtRange) { if (filter.createdAtRange) {
const [start, end] = filter.createdAtRange; const [start, end] = filter.createdAtRange;

View File

@ -0,0 +1,54 @@
module.exports = {
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async up(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'archival_items',
'periodId',
{
type: Sequelize.DataTypes.UUID,
references: {
model: 'periods',
key: 'id',
},
},
{ transaction },
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async down(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn('archival_items', 'periodId', {
transaction,
});
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
};

View File

@ -65,6 +65,14 @@ module.exports = function (sequelize, DataTypes) {
//end loop //end loop
db.archival_items.belongsTo(db.periods, {
as: 'period',
foreignKey: {
name: 'periodId',
},
constraints: false,
});
db.archival_items.hasMany(db.file, { db.archival_items.hasMany(db.file, {
as: 'media', as: 'media',
foreignKey: 'belongsToId', foreignKey: 'belongsToId',

View File

@ -40,26 +40,16 @@ module.exports = function (sequelize, DataTypes) {
); );
periods.associate = (db) => { periods.associate = (db) => {
db.periods.belongsToMany(db.archival_items, {
as: 'archival_items',
foreignKey: {
name: 'periods_archival_itemsId',
},
constraints: false,
through: 'periodsArchival_itemsArchival_items',
});
db.periods.belongsToMany(db.archival_items, {
as: 'archival_items_filter',
foreignKey: {
name: 'periods_archival_itemsId',
},
constraints: false,
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
db.periods.hasMany(db.archival_items, {
as: 'archival_items_period',
foreignKey: {
name: 'periodId',
},
constraints: false,
});
//end loop //end loop
db.periods.belongsTo(db.users, { db.periods.belongsTo(db.users, {

View File

@ -137,6 +137,17 @@ const CardArchival_items = ({
</div> </div>
</dd> </dd>
</div> </div>
<div className='flex justify-between gap-x-4 py-3'>
<dt className=' text-gray-500 dark:text-dark-600'>
Period
</dt>
<dd className='flex items-start gap-x-2'>
<div className='font-medium line-clamp-4'>
{dataFormatter.periodsOneListFormatter(item.period)}
</div>
</dd>
</div>
</dl> </dl>
</li> </li>
))} ))}

View File

@ -97,6 +97,13 @@ const ListArchival_items = ({
.join(', ')} .join(', ')}
</p> </p>
</div> </div>
<div className={'flex-1 px-3'}>
<p className={'text-xs text-gray-500 '}>Period</p>
<p className={'line-clamp-2'}>
{dataFormatter.periodsOneListFormatter(item.period)}
</p>
</div>
</Link> </Link>
<ListActionsPopover <ListActionsPopover
onDelete={onDelete} onDelete={onDelete}

View File

@ -115,6 +115,26 @@ export const loadColumns = async (
), ),
}, },
{
field: 'period',
headerName: 'Period',
flex: 1,
minWidth: 120,
filterable: false,
headerClassName: 'datagrid--header',
cellClassName: 'datagrid--cell',
editable: hasUpdatePermission,
sortable: false,
type: 'singleSelect',
getOptionValue: (value: any) => value?.id,
getOptionLabel: (value: any) => value?.label,
valueOptions: await callOptionsApi('periods'),
valueGetter: (params: GridValueGetterParams) =>
params?.value?.id ?? params?.value,
},
{ {
field: 'actions', field: 'actions',
type: 'actions', type: 'actions',

View File

@ -83,19 +83,6 @@ const CardPeriods = ({
</dd> </dd>
</div> </div>
<div className='flex justify-between gap-x-4 py-3'>
<dt className=' text-gray-500 dark:text-dark-600'>
Archival Items
</dt>
<dd className='flex items-start gap-x-2'>
<div className='font-medium line-clamp-4'>
{dataFormatter
.archival_itemsManyListFormatter(item.archival_items)
.join(', ')}
</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'> <dt className=' text-gray-500 dark:text-dark-600'>
Period From Period From

View File

@ -56,17 +56,6 @@ const ListPeriods = ({
<p className={'line-clamp-2'}>{item.name}</p> <p className={'line-clamp-2'}>{item.name}</p>
</div> </div>
<div className={'flex-1 px-3'}>
<p className={'text-xs text-gray-500 '}>
Archival Items
</p>
<p className={'line-clamp-2'}>
{dataFormatter
.archival_itemsManyListFormatter(item.archival_items)
.join(', ')}
</p>
</div>
<div className={'flex-1 px-3'}> <div className={'flex-1 px-3'}>
<p className={'text-xs text-gray-500 '}>Period From</p> <p className={'text-xs text-gray-500 '}>Period From</p>
<p className={'line-clamp-2'}> <p className={'line-clamp-2'}>

View File

@ -50,25 +50,6 @@ export const loadColumns = async (
editable: hasUpdatePermission, editable: hasUpdatePermission,
}, },
{
field: 'archival_items',
headerName: 'Archival Items',
flex: 1,
minWidth: 120,
filterable: false,
headerClassName: 'datagrid--header',
cellClassName: 'datagrid--cell',
editable: false,
sortable: false,
type: 'singleSelect',
valueFormatter: ({ value }) =>
dataFormatter.archival_itemsManyListFormatter(value).join(', '),
renderEditCell: (params) => (
<DataGridMultiSelect {...params} entityName={'archival_items'} />
),
},
{ {
field: 'period_from', field: 'period_from',
headerName: 'Period From', headerName: 'Period From',

View File

@ -39,21 +39,21 @@ export default {
}); });
}, },
archival_itemsManyListFormatter(val) { periodsManyListFormatter(val) {
if (!val || !val.length) return []; if (!val || !val.length) return [];
return val.map((item) => item.id); return val.map((item) => item.id);
}, },
archival_itemsOneListFormatter(val) { periodsOneListFormatter(val) {
if (!val) return ''; if (!val) return '';
return val.id; return val.id;
}, },
archival_itemsManyListFormatterEdit(val) { periodsManyListFormatterEdit(val) {
if (!val || !val.length) return []; if (!val || !val.length) return [];
return val.map((item) => { return val.map((item) => {
return { id: item.id, label: item.id }; return { id: item.id, label: item.id };
}); });
}, },
archival_itemsOneListFormatterEdit(val) { periodsOneListFormatterEdit(val) {
if (!val) return ''; if (!val) return '';
return { label: val.id, id: val.id }; return { label: val.id, id: val.id };
}, },

View File

@ -45,6 +45,8 @@ const EditArchival_items = () => {
isPublished: false, isPublished: false,
tags: [], tags: [],
period: null,
}; };
const [initialValues, setInitialValues] = useState(initVals); const [initialValues, setInitialValues] = useState(initVals);
@ -142,6 +144,17 @@ const EditArchival_items = () => {
></Field> ></Field>
</FormField> </FormField>
<FormField label='Period' labelFor='period'>
<Field
name='period'
id='period'
component={SelectField}
options={initialValues.period}
itemRef={'periods'}
showField={'id'}
></Field>
</FormField>
<BaseDivider /> <BaseDivider />
<BaseButtons> <BaseButtons>
<BaseButton type='submit' color='info' label='Submit' /> <BaseButton type='submit' color='info' label='Submit' />

View File

@ -45,6 +45,8 @@ const EditArchival_itemsPage = () => {
isPublished: false, isPublished: false,
tags: [], tags: [],
period: null,
}; };
const [initialValues, setInitialValues] = useState(initVals); const [initialValues, setInitialValues] = useState(initVals);
@ -140,6 +142,17 @@ const EditArchival_itemsPage = () => {
></Field> ></Field>
</FormField> </FormField>
<FormField label='Period' labelFor='period'>
<Field
name='period'
id='period'
component={SelectField}
options={initialValues.period}
itemRef={'periods'}
showField={'id'}
></Field>
</FormField>
<BaseDivider /> <BaseDivider />
<BaseButtons> <BaseButtons>
<BaseButton type='submit' color='info' label='Submit' /> <BaseButton type='submit' color='info' label='Submit' />

View File

@ -35,6 +35,8 @@ const Archival_itemsTablesPage = () => {
{ label: 'Label', title: 'label' }, { label: 'Label', title: 'label' },
{ label: 'Description', title: 'description' }, { label: 'Description', title: 'description' },
{ label: 'Period', title: 'period' },
{ label: 'Tags', title: 'tags' }, { label: 'Tags', title: 'tags' },
]); ]);

View File

@ -42,6 +42,8 @@ const initialValues = {
isPublished: false, isPublished: false,
tags: [], tags: [],
period: '',
}; };
const Archival_itemsNew = () => { const Archival_itemsNew = () => {
@ -113,6 +115,16 @@ const Archival_itemsNew = () => {
></Field> ></Field>
</FormField> </FormField>
<FormField label='Period' labelFor='period'>
<Field
name='period'
id='period'
component={SelectField}
options={[]}
itemRef={'periods'}
></Field>
</FormField>
<BaseDivider /> <BaseDivider />
<BaseButtons> <BaseButtons>
<BaseButton type='submit' color='info' label='Submit' /> <BaseButton type='submit' color='info' label='Submit' />

View File

@ -35,6 +35,8 @@ const Archival_itemsTablesPage = () => {
{ label: 'Label', title: 'label' }, { label: 'Label', title: 'label' },
{ label: 'Description', title: 'description' }, { label: 'Description', title: 'description' },
{ label: 'Period', title: 'period' },
{ label: 'Tags', title: 'tags' }, { label: 'Tags', title: 'tags' },
]); ]);

View File

@ -123,6 +123,12 @@ const Archival_itemsView = () => {
</CardBox> </CardBox>
</> </>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Period</p>
<p>{archival_items?.period?.id ?? 'No data'}</p>
</div>
<BaseDivider /> <BaseDivider />
<BaseButton <BaseButton

View File

@ -38,8 +38,6 @@ const EditPeriods = () => {
const initVals = { const initVals = {
name: '', name: '',
archival_items: [],
period_from: new Date(), period_from: new Date(),
period_to: new Date(), period_to: new Date(),
@ -99,17 +97,6 @@ const EditPeriods = () => {
<Field name='name' placeholder='Name' /> <Field name='name' placeholder='Name' />
</FormField> </FormField>
<FormField label='Archival Items' labelFor='archival_items'>
<Field
name='archival_items'
id='archival_items'
component={SelectFieldMany}
options={initialValues.archival_items}
itemRef={'archival_items'}
showField={'id'}
></Field>
</FormField>
<FormField label='Period From'> <FormField label='Period From'>
<DatePicker <DatePicker
dateFormat='yyyy-MM-dd hh:mm' dateFormat='yyyy-MM-dd hh:mm'

View File

@ -38,8 +38,6 @@ const EditPeriodsPage = () => {
const initVals = { const initVals = {
name: '', name: '',
archival_items: [],
period_from: new Date(), period_from: new Date(),
period_to: new Date(), period_to: new Date(),
@ -97,17 +95,6 @@ const EditPeriodsPage = () => {
<Field name='name' placeholder='Name' /> <Field name='name' placeholder='Name' />
</FormField> </FormField>
<FormField label='Archival Items' labelFor='archival_items'>
<Field
name='archival_items'
id='archival_items'
component={SelectFieldMany}
options={initialValues.archival_items}
itemRef={'archival_items'}
showField={'id'}
></Field>
</FormField>
<FormField label='Period From'> <FormField label='Period From'>
<DatePicker <DatePicker
dateFormat='yyyy-MM-dd hh:mm' dateFormat='yyyy-MM-dd hh:mm'

View File

@ -33,8 +33,6 @@ const PeriodsTablesPage = () => {
{ label: 'Period From', title: 'period_from', date: 'true' }, { label: 'Period From', title: 'period_from', date: 'true' },
{ label: 'Period To', title: 'period_to', date: 'true' }, { label: 'Period To', title: 'period_to', date: 'true' },
{ label: 'Archival Items', title: 'archival_items' },
]); ]);
const hasCreatePermission = const hasCreatePermission =

View File

@ -35,8 +35,6 @@ import moment from 'moment';
const initialValues = { const initialValues = {
name: '', name: '',
archival_items: [],
period_from: '', period_from: '',
period_to: '', period_to: '',
@ -73,16 +71,6 @@ const PeriodsNew = () => {
<Field name='name' placeholder='Name' /> <Field name='name' placeholder='Name' />
</FormField> </FormField>
<FormField label='Archival Items' labelFor='archival_items'>
<Field
name='archival_items'
id='archival_items'
itemRef={'archival_items'}
options={[]}
component={SelectFieldMany}
></Field>
</FormField>
<FormField label='Period From'> <FormField label='Period From'>
<Field <Field
type='datetime-local' type='datetime-local'

View File

@ -33,8 +33,6 @@ const PeriodsTablesPage = () => {
{ label: 'Period From', title: 'period_from', date: 'true' }, { label: 'Period From', title: 'period_from', date: 'true' },
{ label: 'Period To', title: 'period_to', date: 'true' }, { label: 'Period To', title: 'period_to', date: 'true' },
{ label: 'Archival Items', title: 'archival_items' },
]); ]);
const hasCreatePermission = const hasCreatePermission =

View File

@ -59,53 +59,6 @@ const PeriodsView = () => {
<p>{periods?.name}</p> <p>{periods?.name}</p>
</div> </div>
<>
<p className={'block font-bold mb-2'}>Archival Items</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>Label</th>
<th>Description</th>
<th>Is Published</th>
</tr>
</thead>
<tbody>
{periods.archival_items &&
Array.isArray(periods.archival_items) &&
periods.archival_items.map((item: any) => (
<tr
key={item.id}
onClick={() =>
router.push(
`/archival_items/archival_items-view/?id=${item.id}`,
)
}
>
<td data-label='label'>{item.label}</td>
<td data-label='description'>{item.description}</td>
<td data-label='isPublished'>
{dataFormatter.booleanFormatter(item.isPublished)}
</td>
</tr>
))}
</tbody>
</table>
</div>
{!periods?.archival_items?.length && (
<div className={'text-center py-4'}>No data</div>
)}
</CardBox>
</>
<FormField label='Period From'> <FormField label='Period From'>
{periods.period_from ? ( {periods.period_from ? (
<DatePicker <DatePicker
@ -144,6 +97,53 @@ const PeriodsView = () => {
)} )}
</FormField> </FormField>
<>
<p className={'block font-bold mb-2'}>Archival_items Period</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>Label</th>
<th>Description</th>
<th>Is Published</th>
</tr>
</thead>
<tbody>
{periods.archival_items_period &&
Array.isArray(periods.archival_items_period) &&
periods.archival_items_period.map((item: any) => (
<tr
key={item.id}
onClick={() =>
router.push(
`/archival_items/archival_items-view/?id=${item.id}`,
)
}
>
<td data-label='label'>{item.label}</td>
<td data-label='description'>{item.description}</td>
<td data-label='isPublished'>
{dataFormatter.booleanFormatter(item.isPublished)}
</td>
</tr>
))}
</tbody>
</table>
</div>
{!periods?.archival_items_period?.length && (
<div className={'text-center py-4'}>No data</div>
)}
</CardBox>
</>
<BaseDivider /> <BaseDivider />
<BaseButton <BaseButton