Autosave: 20260404-180248

This commit is contained in:
Flatlogic Bot 2026-04-04 18:02:49 +00:00
parent 8ceeef1051
commit 18dbc6c578
101 changed files with 3108 additions and 50924 deletions

View File

@ -0,0 +1,96 @@
import { mdiArrowLeft, mdiEyeOutline } from '@mdi/js';
import React from 'react';
import BaseButton from '../BaseButton';
import BaseButtons from '../BaseButtons';
import CardBox from '../CardBox';
import {
emptyValue,
formatPrimitiveValue,
getPrimaryTitle,
getRecordSubtitle,
getSummaryEntries,
humanizeLabel,
} from '../EntityPageUtils';
type Props = {
entityLabel: string;
pluralLabel: string;
listHref: string;
viewHref?: string;
record: any;
children: React.ReactNode;
};
const EnhancedEntityEditShell = ({ entityLabel, pluralLabel, listHref, viewHref, record, children }: Props) => {
const title = getPrimaryTitle(record, `Edit ${entityLabel}`);
const subtitle = getRecordSubtitle(record, `${entityLabel} record`);
const summaryEntries = getSummaryEntries(record, 7);
return (
<div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_320px] xl:items-start">
<div className="rounded-2xl border border-slate-200/80 bg-white p-5 shadow-sm dark:border-dark-700 dark:bg-dark-900">
<div className="mb-6 rounded-xl border border-slate-200/80 bg-slate-50/80 p-5 dark:border-dark-700 dark:bg-dark-800/60">
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
<div className="max-w-2xl">
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400">Edit workspace</p>
<h3 className="mt-2 text-2xl font-semibold text-slate-900 dark:text-slate-100">{title}</h3>
<p className="mt-2 text-sm text-slate-600 dark:text-slate-300">{subtitle}. Update the fields below and keep the record details clear, complete, and ready for downstream users.</p>
</div>
<BaseButtons type="justify-start md:justify-end" className="w-full lg:w-auto" noWrap>
<BaseButton color="white" outline icon={mdiArrowLeft} label={`Back to ${pluralLabel.toLowerCase()}`} href={listHref} />
{viewHref ? <BaseButton color="white" outline icon={mdiEyeOutline} label={`View ${entityLabel.toLowerCase()}`} href={viewHref} /> : null}
</BaseButtons>
</div>
</div>
<div className="grid gap-6 md:grid-cols-2 [&>div:not(:last-child)]:min-w-0 [&>div:not(:last-child)]:rounded-xl [&>div:not(:last-child)]:border [&>div:not(:last-child)]:border-slate-200/80 [&>div:not(:last-child)]:bg-slate-50/50 [&>div:not(:last-child)]:p-4 dark:[&>div:not(:last-child)]:border-dark-700 dark:[&>div:not(:last-child)]:bg-dark-800/40 [&>hr]:md:col-span-2 [&>div:last-child]:md:col-span-2">
{children}
</div>
</div>
<div className="space-y-6 xl:sticky xl:top-6">
<CardBox>
<div className="space-y-5">
<div className="flex items-center gap-3">
<div className="rounded-lg border border-slate-200 bg-slate-50 p-2 text-slate-500 dark:border-dark-700 dark:bg-dark-800 dark:text-slate-300">
<span className="inline-flex"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M4 19H20V21H4V19M17 7L15 5L17 3L19 5L17 7M6 17H4V15L14 5L16 7L6 17Z" /></svg></span>
</div>
<div>
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Editing summary</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Key values stay visible while the form is being updated.</p>
</div>
</div>
<div className="space-y-3">
{summaryEntries.length > 0 ? (
summaryEntries.map(([key, value]) => (
<div key={key} className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{humanizeLabel(key)}</p>
<div className="mt-2 text-sm font-medium text-slate-900 dark:text-slate-100">{value instanceof Date || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? formatPrimitiveValue(key, value) : value || emptyValue}</div>
</div>
))
) : (
<div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
Summary fields will appear here as soon as this record has saved content.
</div>
)}
</div>
</div>
</CardBox>
<CardBox>
<div className="space-y-3">
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Editing guidance</h3>
<ul className="space-y-2 text-sm text-slate-600 dark:text-slate-300">
<li> Keep naming and reference fields consistent with list and dashboard views.</li>
<li> Use notes and description fields to add decision-quality context, not placeholders.</li>
<li> Reset only if you want to discard unsaved changes in this form session.</li>
</ul>
</div>
</CardBox>
</div>
</div>
);
};
export default EnhancedEntityEditShell;

View File

@ -0,0 +1,282 @@
import { mdiArrowLeft, mdiChartTimelineVariant, mdiPencil } from '@mdi/js';
import Head from 'next/head';
import React, { useEffect } from 'react';
import BaseButton from '../BaseButton';
import BaseButtons from '../BaseButtons';
import BaseIcon from '../BaseIcon';
import CardBox from '../CardBox';
import SectionMain from '../SectionMain';
import SectionTitleLineWithButton from '../SectionTitleLineWithButton';
import { getPageTitle } from '../../config';
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
import { useRouter } from 'next/router';
import {
emptyValue,
formatPrimitiveValue,
getChipEntries,
getCollectionPreview,
getMetricCards,
getPrimaryTitle,
getRecordEntries,
getRecordSubtitle,
getRelationLabel,
getSummaryEntries,
humanizeLabel,
isRecordObject,
} from '../EntityPageUtils';
type Props = {
singularLabel: string;
pluralLabel: string;
stateKey: string;
recordKey: string;
fetchRecord: any;
listHref: string;
editHref: (id: string | string[] | undefined) => string;
};
const getBadgeClassName = (value?: string | null) => {
switch (String(value || '').toLowerCase()) {
case 'active':
case 'approved':
case 'completed':
case 'resolved':
case 'settled':
case 'paid':
case 'enabled':
case 'true':
return 'border-emerald-200 bg-emerald-50 text-emerald-700';
case 'submitted':
case 'under_review':
case 'in_progress':
case 'validated':
case 'partial':
case 'draft':
return 'border-blue-200 bg-blue-50 text-blue-700';
case 'on_hold':
case 'blocked':
case 'follow_up_required':
case 'disputed':
case 'pending':
return 'border-amber-200 bg-amber-50 text-amber-700';
case 'critical':
case 'high':
case 'terminated':
case 'cancelled':
case 'closed':
case 'disabled':
case 'false':
return 'border-red-200 bg-red-50 text-red-700';
default:
return 'border-slate-200 bg-slate-50 text-slate-700 dark:border-dark-700 dark:bg-dark-800 dark:text-slate-200';
}
};
const StatusBadge = ({ value }: { value: any }) => (
<span className={`rounded-full border px-2.5 py-1 text-xs font-semibold ${getBadgeClassName(value)}`}>{String(formatPrimitiveValue('status', value))}</span>
);
const DetailItem = ({ label, value }: { label: string; value: React.ReactNode }) => (
<div className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{label}</p>
<div className="mt-2 text-sm leading-6 text-slate-900 dark:text-slate-100">{value || emptyValue}</div>
</div>
);
const MetricCard = ({ label, value, note }: { label: string; value: string; note: string }) => (
<div className="rounded-xl border border-slate-200/80 bg-slate-50/80 p-4 dark:border-dark-700 dark:bg-dark-800/60">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{label}</p>
<p className="mt-3 text-2xl font-semibold text-slate-900 dark:text-slate-100">{value}</p>
<p className="mt-2 text-sm text-slate-600 dark:text-slate-300">{note}</p>
</div>
);
const EntityRecordViewPage = ({ singularLabel, pluralLabel, stateKey, recordKey, fetchRecord, listHref, editHref }: Props) => {
const router = useRouter();
const dispatch = useAppDispatch();
const { id } = router.query;
const sliceState = useAppSelector((state) => (state as any)[stateKey]);
const record = sliceState?.[recordKey];
useEffect(() => {
if (id) {
dispatch(fetchRecord({ id }));
}
}, [dispatch, fetchRecord, id]);
const recordTitle = getPrimaryTitle(record, `View ${singularLabel}`);
const recordSubtitle = getRecordSubtitle(record, `${singularLabel} details`);
const summaryEntries = getSummaryEntries(record, 8);
const metricCards = getMetricCards(record);
const chipEntries = getChipEntries(record);
const { scalarEntries, relationEntries, collectionEntries } = getRecordEntries(record);
const overviewEntries = summaryEntries;
const detailEntries = scalarEntries.filter(([key]) => !overviewEntries.some(([entryKey]) => entryKey === key));
return (
<>
<Head>
<title>{getPageTitle(recordTitle)}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={recordTitle} main>
<BaseButtons type="justify-start md:justify-end" className="w-full md:w-auto" noWrap>
<BaseButton color="white" outline icon={mdiArrowLeft} label={`Back to ${pluralLabel.toLowerCase()}`} onClick={() => router.push(listHref)} />
<BaseButton color="info" icon={mdiPencil} label={`Edit ${singularLabel.toLowerCase()}`} href={editHref(id)} />
</BaseButtons>
</SectionTitleLineWithButton>
<div className="space-y-6">
<CardBox>
<div className="space-y-6">
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
<div className="max-w-3xl">
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400">{singularLabel} workspace</p>
<h2 className="mt-2 text-3xl font-semibold text-slate-900 dark:text-slate-100">{recordTitle}</h2>
<p className="mt-3 text-sm text-slate-600 dark:text-slate-300">{recordSubtitle}</p>
</div>
{chipEntries.length > 0 && (
<div className="flex flex-wrap gap-2">
{chipEntries.map(([key, value]) => (
<div key={key} className="flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3 py-1 dark:border-dark-700 dark:bg-dark-900">
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{humanizeLabel(key)}</span>
<StatusBadge value={value} />
</div>
))}
</div>
)}
</div>
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
{metricCards.map((metric) => (
<MetricCard key={metric.label} label={metric.label} value={metric.value} note={metric.note} />
))}
</div>
</div>
</CardBox>
{!isRecordObject(record) ? (
<CardBox>
<div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-8 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
Loading {singularLabel.toLowerCase()} details or waiting for the record to become available.
</div>
</CardBox>
) : (
<div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_360px]">
<div className="space-y-6">
<CardBox>
<div className="space-y-5">
<div>
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Overview</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Key information is grouped here for faster review and cleaner scanning.</p>
</div>
<div className="grid gap-4 md:grid-cols-2">
{overviewEntries.map(([key, value]) => (
<DetailItem key={key} label={humanizeLabel(key)} value={formatPrimitiveValue(key, value)} />
))}
</div>
</div>
</CardBox>
{detailEntries.length > 0 && (
<CardBox>
<div className="space-y-5">
<div>
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Extended details</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Additional record content is still available, but presented in a cleaner structured layout.</p>
</div>
<div className="grid gap-4 md:grid-cols-2">
{detailEntries.map(([key, value]) => (
<DetailItem key={key} label={humanizeLabel(key)} value={formatPrimitiveValue(key, value)} />
))}
</div>
</div>
</CardBox>
)}
{collectionEntries.map(([key, value]) => {
const items = Array.isArray(value) ? value : [];
const preview = getCollectionPreview(items);
return (
<CardBox key={key}>
<div className="space-y-5">
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">{humanizeLabel(key)}</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Related records are presented as compact cards instead of a raw data dump.</p>
</div>
<span className="rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-semibold uppercase tracking-[0.14em] text-slate-600 dark:border-dark-700 dark:bg-dark-800 dark:text-slate-300">
{items.length} records
</span>
</div>
{preview.length > 0 ? (
<div className="grid gap-4 md:grid-cols-2">
{preview.map((item) => (
<div key={item.key} className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
<div className="flex items-start justify-between gap-3">
<p className="font-semibold text-slate-900 dark:text-slate-100">{item.title}</p>
<div className="rounded-lg border border-slate-200 bg-white p-2 text-slate-500 dark:border-dark-700 dark:bg-dark-900 dark:text-slate-300">
<BaseIcon path={mdiChartTimelineVariant} size={18} />
</div>
</div>
{item.details.length > 0 ? (
<dl className="mt-4 space-y-3">
{item.details.map((detail) => (
<div key={`${item.key}-${detail.label}`}>
<dt className="text-xs font-semibold uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{detail.label}</dt>
<dd className="mt-1 text-sm text-slate-700 dark:text-slate-200">{detail.value || emptyValue}</dd>
</div>
))}
</dl>
) : (
<p className="mt-4 text-sm text-slate-600 dark:text-slate-300">No additional preview fields are available for this related record.</p>
)}
</div>
))}
</div>
) : (
<div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
No related records have been attached here yet.
</div>
)}
</div>
</CardBox>
);
})}
</div>
<div className="space-y-6">
<CardBox>
<div className="space-y-5">
<div>
<h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Connected records</h3>
<p className="mt-1 text-sm text-slate-600 dark:text-slate-300">Direct linked records are summarized here so users can see context without parsing nested JSON-like sections.</p>
</div>
<div className="space-y-4">
{relationEntries.length > 0 ? (
relationEntries.map(([key, value]) => (
<div key={key} className="rounded-xl border border-slate-200/80 bg-slate-50/70 p-4 dark:border-dark-700 dark:bg-dark-800/60">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-400">{humanizeLabel(key)}</p>
<div className="mt-2 text-sm font-medium text-slate-900 dark:text-slate-100">{getRelationLabel(value)}</div>
</div>
))
) : (
<div className="rounded-xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-sm text-slate-600 dark:border-dark-700 dark:bg-dark-800/50 dark:text-slate-300">
No linked records are available on this item yet.
</div>
)}
</div>
</div>
</CardBox>
</div>
</div>
)}
</div>
</SectionMain>
</>
);
};
export default EntityRecordViewPage;

View File

@ -0,0 +1,317 @@
import React from 'react';
import dayjs from 'dayjs';
const EMPTY_VALUE = 'Not yet recorded';
const SYSTEM_FIELDS = new Set([
'id',
'createdAt',
'updatedAt',
'deletedAt',
'created_at',
'updated_at',
'deleted_at',
'password',
'passwordHash',
'salt',
]);
const PRIMARY_TITLE_FIELDS = [
'name',
'title',
'label',
'subject',
'project_name',
'program_name',
'contract_title',
'contract_number',
'code',
'project_code',
'email',
'firstName',
'lastName',
];
const SUMMARY_FIELD_PRIORITY = [
'name',
'title',
'label',
'code',
'project_code',
'contract_number',
'status',
'state',
'phase',
'priority',
'risk_level',
'type',
'category',
'organization',
'program',
'project',
'vendor',
'department',
'assigned_to',
'requested_by',
'requested_at',
'due_date',
'start_date',
'end_date',
'amount',
'budget_amount',
'contract_value',
'currency',
];
const CHIP_FIELDS = ['status', 'state', 'phase', 'priority', 'risk_level', 'type', 'category'];
const DATE_SUFFIXES = ['_at', '_date'];
const DATE_KEYWORDS = ['date', 'time', 'deadline'];
const AMOUNT_KEYWORDS = ['amount', 'value', 'cost', 'budget', 'total', 'price', 'percent'];
export const emptyValue = EMPTY_VALUE;
export const titleCase = (value?: string | null) => {
if (!value) {
return '';
}
return value
.replace(/_/g, ' ')
.replace(/\b\w/g, (match) => match.toUpperCase());
};
export const singularizeLabel = (value: string) => {
if (value.endsWith('ies')) {
return `${value.slice(0, -3)}y`;
}
if (value.endsWith('ches') || value.endsWith('shes') || value.endsWith('xes') || value.endsWith('zes')) {
return value.slice(0, -2);
}
if (value.endsWith('ses') && !value.endsWith('issues') && !value.endsWith('buses')) {
return value.slice(0, -1);
}
if (value.endsWith('s')) {
return value.slice(0, -1);
}
return value;
};
export const humanizeLabel = (key: string) => {
return titleCase(
key
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
.replace(/_/g, ' ')
.replace(/\bid\b/i, 'ID')
.trim(),
);
};
export const isRecordObject = (value: any) => {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);
};
export const isDateLikeKey = (key: string) => {
return DATE_SUFFIXES.some((suffix) => key.endsWith(suffix)) || DATE_KEYWORDS.some((part) => key.includes(part));
};
export const isAmountLikeKey = (key: string) => {
return AMOUNT_KEYWORDS.some((part) => key.includes(part));
};
export const stripHtml = (value: string) => value.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim();
export const formatPrimitiveValue = (key: string, value: any): React.ReactNode => {
if (value === null || value === undefined || value === '') {
return EMPTY_VALUE;
}
if (typeof value === 'boolean') {
return value ? 'Yes' : 'No';
}
if (typeof value === 'number') {
if (key.toLowerCase().includes('percent')) {
return `${value}%`;
}
return value.toLocaleString();
}
if (value instanceof Date || (typeof value === 'string' && isDateLikeKey(key) && dayjs(value).isValid())) {
return dayjs(value).format('DD MMM YYYY HH:mm');
}
if (typeof value === 'string') {
if (value.trim().startsWith('<') && value.includes('>')) {
const stripped = stripHtml(value);
return stripped || EMPTY_VALUE;
}
return value;
}
return String(value);
};
export const getRelationLabel = (value: any) => {
if (!isRecordObject(value)) {
return EMPTY_VALUE;
}
const candidates = ['name', 'title', 'label', 'code', 'project_code', 'contract_number', 'email', 'id'];
for (const candidate of candidates) {
if (value[candidate]) {
return formatPrimitiveValue(candidate, value[candidate]);
}
}
const visibleEntry = Object.entries(value).find(([entryKey, entryValue]) => !SYSTEM_FIELDS.has(entryKey) && !isRecordObject(entryValue) && !Array.isArray(entryValue));
return visibleEntry ? formatPrimitiveValue(visibleEntry[0], visibleEntry[1]) : EMPTY_VALUE;
};
export const getPrimaryTitle = (record: any, fallback: string) => {
if (!isRecordObject(record)) {
return fallback;
}
const firstName = record.firstName || record.first_name;
const lastName = record.lastName || record.last_name;
if (firstName || lastName) {
return [firstName, lastName].filter(Boolean).join(' ');
}
for (const field of PRIMARY_TITLE_FIELDS) {
if (record[field]) {
const value = formatPrimitiveValue(field, record[field]);
return typeof value === 'string' ? value : fallback;
}
}
return fallback;
};
export const getRecordSubtitle = (record: any, fallback: string) => {
if (!isRecordObject(record)) {
return fallback;
}
const referenceFields = ['code', 'project_code', 'contract_number', 'email', 'id'];
const reference = referenceFields.find((field) => record[field]);
if (!reference) {
return fallback;
}
return `${humanizeLabel(reference)}: ${formatPrimitiveValue(reference, record[reference])}`;
};
export const getRecordEntries = (record: any) => {
if (!isRecordObject(record)) {
return { scalarEntries: [], relationEntries: [], collectionEntries: [] };
}
const scalarEntries = Object.entries(record).filter(([key, value]) => {
return !SYSTEM_FIELDS.has(key) && !Array.isArray(value) && !isRecordObject(value);
});
const relationEntries = Object.entries(record).filter(([key, value]) => {
return !SYSTEM_FIELDS.has(key) && isRecordObject(value);
});
const collectionEntries = Object.entries(record).filter(([key, value]) => {
return !SYSTEM_FIELDS.has(key) && Array.isArray(value);
});
return { scalarEntries, relationEntries, collectionEntries };
};
export const sortEntries = (entries: Array<[string, any]>) => {
return [...entries].sort((left, right) => {
const leftIndex = SUMMARY_FIELD_PRIORITY.indexOf(left[0]);
const rightIndex = SUMMARY_FIELD_PRIORITY.indexOf(right[0]);
if (leftIndex !== -1 || rightIndex !== -1) {
return (leftIndex === -1 ? 999 : leftIndex) - (rightIndex === -1 ? 999 : rightIndex);
}
return humanizeLabel(left[0]).localeCompare(humanizeLabel(right[0]));
});
};
export const getSummaryEntries = (record: any, limit = 8) => {
const { scalarEntries, relationEntries } = getRecordEntries(record);
const scalar = sortEntries(scalarEntries);
const relation = sortEntries(relationEntries)
.filter(([key]) => !CHIP_FIELDS.includes(key))
.map(([key, value]) => [key, getRelationLabel(value)] as [string, React.ReactNode]);
return [...scalar, ...relation].slice(0, limit);
};
export const getChipEntries = (record: any) => {
if (!isRecordObject(record)) {
return [] as Array<[string, any]>;
}
return CHIP_FIELDS.filter((field) => record[field]).map((field) => [field, record[field]] as [string, any]);
};
export const getMetricCards = (record: any) => {
const { collectionEntries } = getRecordEntries(record);
const metrics = [
{
label: 'Linked sections',
value: collectionEntries.length.toString(),
note: collectionEntries.length ? 'Related collections are shown below.' : 'No related collections are attached yet.',
},
];
const importantEntries = [
['status', record?.status],
['start_date', record?.start_date],
['end_date', record?.end_date],
['budget_amount', record?.budget_amount ?? record?.amount ?? record?.contract_value],
].filter(([, value]) => value !== undefined && value !== null && value !== '');
for (const [key, value] of importantEntries.slice(0, 3)) {
metrics.push({
label: humanizeLabel(key),
value: String(formatPrimitiveValue(key, value)),
note: key === 'budget_amount' ? 'Tracked financial figure for this record.' : 'Key operating signal for this record.',
});
}
return metrics.slice(0, 4);
};
export const getCollectionPreview = (items: any[]) => {
return items.slice(0, 6).map((item, index) => {
if (!isRecordObject(item)) {
return {
key: String(index),
title: formatPrimitiveValue('value', item),
details: [],
};
}
const title = getPrimaryTitle(item, `Record ${index + 1}`);
const details = sortEntries(
Object.entries(item).filter(([key, value]) => !SYSTEM_FIELDS.has(key) && !Array.isArray(value) && !isRecordObject(value)),
)
.filter(([key]) => !PRIMARY_TITLE_FIELDS.includes(key))
.slice(0, 4)
.map(([key, value]) => ({
label: humanizeLabel(key),
value: formatPrimitiveValue(key, value),
}));
return {
key: String(item.id || index),
title,
details,
};
});
};

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditAllocationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='BudgetLine' labelFor='budget_line'>
<EnhancedEntityEditShell
entityLabel="Allocation"
pluralLabel="Allocations"
listHref="/allocations/allocations-list"
viewHref={`/allocations/allocations-view/?id=${id}`}
record={initialValues}
>
<FormField label='BudgetLine' labelFor='budget_line'>
<Field
name='budget_line'
id='budget_line'
@ -1115,6 +1101,7 @@ const EditAllocationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/allocations/allocations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,841 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/allocations/allocationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const AllocationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { allocations } = useAppSelector((state) => state.allocations)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View allocations')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View allocations')} main>
<BaseButton
color='info'
label='Edit'
href={`/allocations/allocations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BudgetLine</p>
<p>{allocations?.budget_line?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Province</p>
<p>{allocations?.province?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Department</p>
<p>{allocations?.department?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AllocationAmount</p>
<p>{allocations?.amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{allocations?.currency ?? 'No data'}</p>
</div>
<FormField label='AllocatedAt'>
{allocations.allocated_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={allocations.allocated_at ?
new Date(
dayjs(allocations.allocated_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No AllocatedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{allocations?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={allocations?.notes} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{allocations?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/allocations/allocations-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/allocations/allocationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const AllocationsView = () => (
<EntityRecordViewPage
singularLabel="Allocation"
pluralLabel="Allocations"
stateKey="allocations"
recordKey="allocations"
fetchRecord={fetch}
listHref="/allocations/allocations-list"
editHref={(id) => `/allocations/allocations-edit/?id=${id ?? ''}`}
/>
);
AllocationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_ALLOCATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_ALLOCATIONS'}>{page}</LayoutAuthenticated>;
};
export default AllocationsView;
export default AllocationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditApproval_stepsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Workflow' labelFor='workflow'>
<EnhancedEntityEditShell
entityLabel="Approval Step"
pluralLabel="Approval Steps"
listHref="/approval_steps/approval_steps-list"
viewHref={`/approval_steps/approval_steps-view/?id=${id}`}
record={initialValues}
>
<FormField label='Workflow' labelFor='workflow'>
<Field
name='workflow'
id='workflow'
@ -1107,6 +1093,7 @@ const EditApproval_stepsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/approval_steps/approval_steps-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,954 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/approval_steps/approval_stepsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Approval_stepsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { approval_steps } = useAppSelector((state) => state.approval_steps)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View approval_steps')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View approval_steps')} main>
<BaseButton
color='info'
label='Edit'
href={`/approval_steps/approval_steps-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Workflow</p>
<p>{approval_steps?.workflow?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>StepOrder</p>
<p>{approval_steps?.step_order || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>StepName</p>
<p>{approval_steps?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ApproverRole</p>
<p>{approval_steps?.approver_role?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ApproverDepartment</p>
<p>{approval_steps?.approver_department?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>MinimumAmount</p>
<p>{approval_steps?.min_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>MaximumAmount</p>
<p>{approval_steps?.max_amount || 'No data'}</p>
</div>
<FormField label='RequiresComment'>
<SwitchField
field={{name: 'requires_comment', value: approval_steps?.requires_comment}}
form={{setFieldValue: () => null}}
disabled
/>
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{approval_steps?.organizations?.name ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Approvals CurrentStep</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>RecordType</th>
<th>RecordKey</th>
<th>Status</th>
<th>RequestedAt</th>
<th>DecidedAt</th>
<th>DecisionComment</th>
<th>RejectionReason</th>
</tr>
</thead>
<tbody>
{approval_steps.approvals_step && Array.isArray(approval_steps.approvals_step) &&
approval_steps.approvals_step.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/approvals/approvals-view/?id=${item.id}`)}>
<td data-label="record_type">
{ item.record_type }
</td>
<td data-label="record_key">
{ item.record_key }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="requested_at">
{ dataFormatter.dateTimeFormatter(item.requested_at) }
</td>
<td data-label="decided_at">
{ dataFormatter.dateTimeFormatter(item.decided_at) }
</td>
<td data-label="decision_comment">
{ item.decision_comment }
</td>
<td data-label="rejection_reason">
{ item.rejection_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!approval_steps?.approvals_step?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/approval_steps/approval_steps-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/approval_steps/approval_stepsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ApprovalStepsView = () => (
<EntityRecordViewPage
singularLabel="Approval Step"
pluralLabel="Approval Steps"
stateKey="approval_steps"
recordKey="approval_steps"
fetchRecord={fetch}
listHref="/approval_steps/approval_steps-list"
editHref={(id) => `/approval_steps/approval_steps-edit/?id=${id ?? ''}`}
/>
);
ApprovalStepsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_APPROVAL_STEPS'}>{page}</LayoutAuthenticated>;
};
Approval_stepsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_APPROVAL_STEPS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Approval_stepsView;
export default ApprovalStepsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -231,28 +232,14 @@ const EditApproval_workflowsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Approval Workflow"
pluralLabel="Approval Workflows"
listHref="/approval_workflows/approval_workflows-list"
viewHref={`/approval_workflows/approval_workflows-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -563,6 +550,7 @@ const EditApproval_workflowsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/approval_workflows/approval_workflows-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,606 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/approval_workflows/approval_workflowsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Approval_workflowsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { approval_workflows } = useAppSelector((state) => state.approval_workflows)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View approval_workflows')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View approval_workflows')} main>
<BaseButton
color='info'
label='Edit'
href={`/approval_workflows/approval_workflows-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{approval_workflows?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>WorkflowName</p>
<p>{approval_workflows?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Module</p>
<p>{approval_workflows?.module ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordType</p>
<p>{approval_workflows?.record_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{approval_workflows?.status ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Approval_steps Workflow</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>StepOrder</th>
<th>StepName</th>
<th>MinimumAmount</th>
<th>MaximumAmount</th>
<th>RequiresComment</th>
</tr>
</thead>
<tbody>
{approval_workflows.approval_steps_workflow && Array.isArray(approval_workflows.approval_steps_workflow) &&
approval_workflows.approval_steps_workflow.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/approval_steps/approval_steps-view/?id=${item.id}`)}>
<td data-label="step_order">
{ item.step_order }
</td>
<td data-label="name">
{ item.name }
</td>
<td data-label="min_amount">
{ item.min_amount }
</td>
<td data-label="max_amount">
{ item.max_amount }
</td>
<td data-label="requires_comment">
{ dataFormatter.booleanFormatter(item.requires_comment) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!approval_workflows?.approval_steps_workflow?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Approvals Workflow</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>RecordType</th>
<th>RecordKey</th>
<th>Status</th>
<th>RequestedAt</th>
<th>DecidedAt</th>
<th>DecisionComment</th>
<th>RejectionReason</th>
</tr>
</thead>
<tbody>
{approval_workflows.approvals_workflow && Array.isArray(approval_workflows.approvals_workflow) &&
approval_workflows.approvals_workflow.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/approvals/approvals-view/?id=${item.id}`)}>
<td data-label="record_type">
{ item.record_type }
</td>
<td data-label="record_key">
{ item.record_key }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="requested_at">
{ dataFormatter.dateTimeFormatter(item.requested_at) }
</td>
<td data-label="decided_at">
{ dataFormatter.dateTimeFormatter(item.decided_at) }
</td>
<td data-label="decision_comment">
{ item.decision_comment }
</td>
<td data-label="rejection_reason">
{ item.rejection_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!approval_workflows?.approvals_workflow?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/approval_workflows/approval_workflows-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/approval_workflows/approval_workflowsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ApprovalWorkflowsView = () => (
<EntityRecordViewPage
singularLabel="Approval Workflow"
pluralLabel="Approval Workflows"
stateKey="approval_workflows"
recordKey="approval_workflows"
fetchRecord={fetch}
listHref="/approval_workflows/approval_workflows-list"
editHref={(id) => `/approval_workflows/approval_workflows-edit/?id=${id ?? ''}`}
/>
);
ApprovalWorkflowsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_APPROVAL_WORKFLOWS'}>{page}</LayoutAuthenticated>;
};
Approval_workflowsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_APPROVAL_WORKFLOWS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Approval_workflowsView;
export default ApprovalWorkflowsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -427,28 +428,14 @@ const EditApprovalsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Approval"
pluralLabel="Approvals"
listHref="/approvals/approvals-list"
viewHref={`/approvals/approvals-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1412,6 +1399,7 @@ const EditApprovalsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/approvals/approvals-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditAudit_logsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Audit Log"
pluralLabel="Audit Logs"
listHref="/audit_logs/audit_logs-list"
viewHref={`/audit_logs/audit_logs-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -891,6 +878,7 @@ const EditAudit_logsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/audit_logs/audit_logs-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,636 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/audit_logs/audit_logsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Audit_logsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { audit_logs } = useAppSelector((state) => state.audit_logs)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View audit_logs')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View audit_logs')} main>
<BaseButton
color='info'
label='Edit'
href={`/audit_logs/audit_logs-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{audit_logs?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ActorUser</p>
<p>{audit_logs?.actor_user?.firstName ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Action</p>
<p>{audit_logs?.action}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>EntityName</p>
<p>{audit_logs?.entity_name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordKey</p>
<p>{audit_logs?.record_key}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={audit_logs?.summary} />
</FormField>
<FormField label='OccurredAt'>
{audit_logs.occurred_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={audit_logs.occurred_at ?
new Date(
dayjs(audit_logs.occurred_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No OccurredAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>IPAddress</p>
<p>{audit_logs?.ip_address}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={audit_logs?.user_agent} />
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/audit_logs/audit_logs-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/audit_logs/audit_logsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const AuditLogsView = () => (
<EntityRecordViewPage
singularLabel="Audit Log"
pluralLabel="Audit Logs"
stateKey="audit_logs"
recordKey="audit_logs"
fetchRecord={fetch}
listHref="/audit_logs/audit_logs-list"
editHref={(id) => `/audit_logs/audit_logs-edit/?id=${id ?? ''}`}
/>
);
AuditLogsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_AUDIT_LOGS'}>{page}</LayoutAuthenticated>;
};
Audit_logsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_AUDIT_LOGS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Audit_logsView;
export default AuditLogsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditAwardsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Award"
pluralLabel="Awards"
listHref="/awards/awards-list"
viewHref={`/awards/awards-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1016,6 +1003,7 @@ const EditAwardsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/awards/awards-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,900 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/awards/awardsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const AwardsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { awards } = useAppSelector((state) => state.awards)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View awards')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View awards')} main>
<BaseButton
color='info'
label='Edit'
href={`/awards/awards-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{awards?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Tender</p>
<p>{awards?.tender?.tender_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>WinningBid</p>
<p>{awards?.winning_bid?.bid_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AwardNumber</p>
<p>{awards?.award_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AwardAmount</p>
<p>{awards?.award_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{awards?.currency ?? 'No data'}</p>
</div>
<FormField label='DecisionDate'>
{awards.decision_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={awards.decision_date ?
new Date(
dayjs(awards.decision_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DecisionDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{awards?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AwardMemo</p>
{awards.award_memo
? <p dangerouslySetInnerHTML={{__html: awards.award_memo}}/>
: <p>No data</p>
}
</div>
<>
<p className={'block font-bold mb-2'}>Contracts Award</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ContractNumber</th>
<th>ContractTitle</th>
<th>ContractType</th>
<th>ContractValue</th>
<th>Currency</th>
<th>StartDate</th>
<th>EndDate</th>
<th>Status</th>
<th>RetentionPercent</th>
<th>PenaltyRatePercent</th>
<th>SignedAt</th>
</tr>
</thead>
<tbody>
{awards.contracts_award && Array.isArray(awards.contracts_award) &&
awards.contracts_award.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/contracts/contracts-view/?id=${item.id}`)}>
<td data-label="contract_number">
{ item.contract_number }
</td>
<td data-label="title">
{ item.title }
</td>
<td data-label="contract_type">
{ item.contract_type }
</td>
<td data-label="contract_value">
{ item.contract_value }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="start_date">
{ dataFormatter.dateTimeFormatter(item.start_date) }
</td>
<td data-label="end_date">
{ dataFormatter.dateTimeFormatter(item.end_date) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="retention_percent">
{ item.retention_percent }
</td>
<td data-label="penalty_rate_percent">
{ item.penalty_rate_percent }
</td>
<td data-label="signed_at">
{ dataFormatter.dateTimeFormatter(item.signed_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!awards?.contracts_award?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/awards/awards-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/awards/awardsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const AwardsView = () => (
<EntityRecordViewPage
singularLabel="Award"
pluralLabel="Awards"
stateKey="awards"
recordKey="awards"
fetchRecord={fetch}
listHref="/awards/awards-list"
editHref={(id) => `/awards/awards-edit/?id=${id ?? ''}`}
/>
);
AwardsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_AWARDS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_AWARDS'}>{page}</LayoutAuthenticated>;
};
export default AwardsView;
export default AwardsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -427,29 +428,14 @@ const EditBeneficiariesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Grant' labelFor='grant'>
<EnhancedEntityEditShell
entityLabel="Beneficiary"
pluralLabel="Beneficiaries"
listHref="/beneficiaries/beneficiaries-list"
viewHref={`/beneficiaries/beneficiaries-view/?id=${id}`}
record={initialValues}
>
<FormField label='Grant' labelFor='grant'>
<Field
name='grant'
id='grant'
@ -1225,6 +1211,7 @@ const EditBeneficiariesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/beneficiaries/beneficiaries-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,925 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/beneficiaries/beneficiariesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const BeneficiariesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { beneficiaries } = useAppSelector((state) => state.beneficiaries)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View beneficiaries')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View beneficiaries')} main>
<BaseButton
color='info'
label='Edit'
href={`/beneficiaries/beneficiaries-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Grant</p>
<p>{beneficiaries?.grant?.call_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Province</p>
<p>{beneficiaries?.province?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BeneficiaryName</p>
<p>{beneficiaries?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BeneficiaryType</p>
<p>{beneficiaries?.beneficiary_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RegistrationNumber</p>
<p>{beneficiaries?.registration_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ContactEmail</p>
<p>{beneficiaries?.contact_email}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ContactPhone</p>
<p>{beneficiaries?.contact_phone}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ApprovedAmount</p>
<p>{beneficiaries?.approved_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{beneficiaries?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{beneficiaries?.status ?? 'No data'}</p>
</div>
<FormField label='ApprovedAt'>
{beneficiaries.approved_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={beneficiaries.approved_at ?
new Date(
dayjs(beneficiaries.approved_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ApprovedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{beneficiaries?.organizations?.name ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Grant_applications Beneficiary</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ApplicationReference</th>
<th>SubmittedAt</th>
<th>RequestedAmount</th>
<th>Currency</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{beneficiaries.grant_applications_beneficiary && Array.isArray(beneficiaries.grant_applications_beneficiary) &&
beneficiaries.grant_applications_beneficiary.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/grant_applications/grant_applications-view/?id=${item.id}`)}>
<td data-label="application_reference">
{ item.application_reference }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="requested_amount">
{ item.requested_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!beneficiaries?.grant_applications_beneficiary?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/beneficiaries/beneficiaries-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/beneficiaries/beneficiariesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const BeneficiariesView = () => (
<EntityRecordViewPage
singularLabel="Beneficiary"
pluralLabel="Beneficiaries"
stateKey="beneficiaries"
recordKey="beneficiaries"
fetchRecord={fetch}
listHref="/beneficiaries/beneficiaries-list"
editHref={(id) => `/beneficiaries/beneficiaries-edit/?id=${id ?? ''}`}
/>
);
BeneficiariesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_BENEFICIARIES'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_BENEFICIARIES'}>{page}</LayoutAuthenticated>;
};
export default BeneficiariesView;
export default BeneficiariesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditBid_evaluationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Bid' labelFor='bid'>
<EnhancedEntityEditShell
entityLabel="Bid Evaluation"
pluralLabel="Bid Evaluations"
listHref="/bid_evaluations/bid_evaluations-list"
viewHref={`/bid_evaluations/bid_evaluations-view/?id=${id}`}
record={initialValues}
>
<FormField label='Bid' labelFor='bid'>
<Field
name='bid'
id='bid'
@ -1007,6 +993,7 @@ const EditBid_evaluationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/bid_evaluations/bid_evaluations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,739 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/bid_evaluations/bid_evaluationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Bid_evaluationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { bid_evaluations } = useAppSelector((state) => state.bid_evaluations)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View bid_evaluations')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View bid_evaluations')} main>
<BaseButton
color='info'
label='Edit'
href={`/bid_evaluations/bid_evaluations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Bid</p>
<p>{bid_evaluations?.bid?.bid_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>LeadEvaluator</p>
<p>{bid_evaluations?.lead_evaluator_user?.firstName ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TechnicalScore</p>
<p>{bid_evaluations?.technical_score || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FinancialScore</p>
<p>{bid_evaluations?.financial_score || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TotalScore</p>
<p>{bid_evaluations?.total_score || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Recommendation</p>
<p>{bid_evaluations?.recommendation ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={bid_evaluations?.justification} />
</FormField>
<FormField label='EvaluatedAt'>
{bid_evaluations.evaluated_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={bid_evaluations.evaluated_at ?
new Date(
dayjs(bid_evaluations.evaluated_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EvaluatedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{bid_evaluations?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/bid_evaluations/bid_evaluations-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/bid_evaluations/bid_evaluationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const BidEvaluationsView = () => (
<EntityRecordViewPage
singularLabel="Bid Evaluation"
pluralLabel="Bid Evaluations"
stateKey="bid_evaluations"
recordKey="bid_evaluations"
fetchRecord={fetch}
listHref="/bid_evaluations/bid_evaluations-list"
editHref={(id) => `/bid_evaluations/bid_evaluations-edit/?id=${id ?? ''}`}
/>
);
BidEvaluationsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_BID_EVALUATIONS'}>{page}</LayoutAuthenticated>;
};
Bid_evaluationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_BID_EVALUATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Bid_evaluationsView;
export default BidEvaluationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditBidsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Tender' labelFor='tender'>
<EnhancedEntityEditShell
entityLabel="Bid"
pluralLabel="Bids"
listHref="/bids/bids-list"
viewHref={`/bids/bids-view/?id=${id}`}
record={initialValues}
>
<FormField label='Tender' labelFor='tender'>
<Field
name='tender'
id='tender'
@ -1014,6 +1000,7 @@ const EditBidsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/bids/bids-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,927 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/bids/bidsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const BidsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { bids } = useAppSelector((state) => state.bids)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View bids')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View bids')} main>
<BaseButton
color='info'
label='Edit'
href={`/bids/bids-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Tender</p>
<p>{bids?.tender?.tender_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Vendor</p>
<p>{bids?.vendor?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BidReference</p>
<p>{bids?.bid_reference}</p>
</div>
<FormField label='SubmittedAt'>
{bids.submitted_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={bids.submitted_at ?
new Date(
dayjs(bids.submitted_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No SubmittedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BidAmount</p>
<p>{bids?.bid_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{bids?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{bids?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={bids?.notes} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{bids?.organizations?.name ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Bid_evaluations Bid</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>TechnicalScore</th>
<th>FinancialScore</th>
<th>TotalScore</th>
<th>Recommendation</th>
<th>Justification</th>
<th>EvaluatedAt</th>
</tr>
</thead>
<tbody>
{bids.bid_evaluations_bid && Array.isArray(bids.bid_evaluations_bid) &&
bids.bid_evaluations_bid.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/bid_evaluations/bid_evaluations-view/?id=${item.id}`)}>
<td data-label="technical_score">
{ item.technical_score }
</td>
<td data-label="financial_score">
{ item.financial_score }
</td>
<td data-label="total_score">
{ item.total_score }
</td>
<td data-label="recommendation">
{ item.recommendation }
</td>
<td data-label="justification">
{ item.justification }
</td>
<td data-label="evaluated_at">
{ dataFormatter.dateTimeFormatter(item.evaluated_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!bids?.bid_evaluations_bid?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Awards WinningBid</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>AwardNumber</th>
<th>AwardAmount</th>
<th>Currency</th>
<th>DecisionDate</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{bids.awards_winning_bid && Array.isArray(bids.awards_winning_bid) &&
bids.awards_winning_bid.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/awards/awards-view/?id=${item.id}`)}>
<td data-label="award_number">
{ item.award_number }
</td>
<td data-label="award_amount">
{ item.award_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="decision_date">
{ dataFormatter.dateTimeFormatter(item.decision_date) }
</td>
<td data-label="status">
{ item.status }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!bids?.awards_winning_bid?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/bids/bids-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/bids/bidsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const BidsView = () => (
<EntityRecordViewPage
singularLabel="Bid"
pluralLabel="Bids"
stateKey="bids"
recordKey="bids"
fetchRecord={fetch}
listHref="/bids/bids-list"
editHref={(id) => `/bids/bids-edit/?id=${id ?? ''}`}
/>
);
BidsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_BIDS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_BIDS'}>{page}</LayoutAuthenticated>;
};
export default BidsView;
export default BidsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,29 +400,14 @@ const EditBudget_linesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='BudgetProgram' labelFor='budget_program'>
<EnhancedEntityEditShell
entityLabel="Budget Line"
pluralLabel="Budget Lines"
listHref="/budget_lines/budget_lines-list"
viewHref={`/budget_lines/budget_lines-view/?id=${id}`}
record={initialValues}
>
<FormField label='BudgetProgram' labelFor='budget_program'>
<Field
name='budget_program'
id='budget_program'
@ -1038,6 +1024,7 @@ const EditBudget_linesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/budget_lines/budget_lines-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditBudget_programsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Budget Program"
pluralLabel="Budget Programs"
listHref="/budget_programs/budget_programs-list"
viewHref={`/budget_programs/budget_programs-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1004,6 +991,7 @@ const EditBudget_programsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/budget_programs/budget_programs-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,852 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/budget_programs/budget_programsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Budget_programsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { budget_programs } = useAppSelector((state) => state.budget_programs)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View budget_programs')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View budget_programs')} main>
<BaseButton
color='info'
label='Edit'
href={`/budget_programs/budget_programs-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{budget_programs?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FiscalYear</p>
<p>{budget_programs?.fiscal_year?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FundingSource</p>
<p>{budget_programs?.funding_source?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ProgramName</p>
<p>{budget_programs?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ProgramCode</p>
<p>{budget_programs?.code}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={budget_programs?.objective} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{budget_programs?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ApprovedAmount</p>
<p>{budget_programs?.approved_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{budget_programs?.currency ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Budget_lines BudgetProgram</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>BudgetLineName</th>
<th>BudgetLineCode</th>
<th>Description</th>
<th>Category</th>
<th>ApprovedAmount</th>
<th>CommittedAmount</th>
<th>DisbursedAmount</th>
<th>Currency</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{budget_programs.budget_lines_budget_program && Array.isArray(budget_programs.budget_lines_budget_program) &&
budget_programs.budget_lines_budget_program.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/budget_lines/budget_lines-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="code">
{ item.code }
</td>
<td data-label="description">
{ item.description }
</td>
<td data-label="category">
{ item.category }
</td>
<td data-label="approved_amount">
{ item.approved_amount }
</td>
<td data-label="committed_amount">
{ item.committed_amount }
</td>
<td data-label="disbursed_amount">
{ item.disbursed_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!budget_programs?.budget_lines_budget_program?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/budget_programs/budget_programs-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/budget_programs/budget_programsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const BudgetProgramsView = () => (
<EntityRecordViewPage
singularLabel="Budget Program"
pluralLabel="Budget Programs"
stateKey="budget_programs"
recordKey="budget_programs"
fetchRecord={fetch}
listHref="/budget_programs/budget_programs-list"
editHref={(id) => `/budget_programs/budget_programs-edit/?id=${id ?? ''}`}
/>
);
BudgetProgramsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_BUDGET_PROGRAMS'}>{page}</LayoutAuthenticated>;
};
Budget_programsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_BUDGET_PROGRAMS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Budget_programsView;
export default BudgetProgramsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,28 +372,14 @@ const EditBudget_reallocationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Budget Reallocation"
pluralLabel="Budget Reallocations"
listHref="/budget_reallocations/budget_reallocations-list"
viewHref={`/budget_reallocations/budget_reallocations-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1285,6 +1272,7 @@ const EditBudget_reallocationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/budget_reallocations/budget_reallocations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,975 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/budget_reallocations/budget_reallocationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Budget_reallocationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { budget_reallocations } = useAppSelector((state) => state.budget_reallocations)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View budget_reallocations')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View budget_reallocations')} main>
<BaseButton
color='info'
label='Edit'
href={`/budget_reallocations/budget_reallocations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{budget_reallocations?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FiscalYear</p>
<p>{budget_reallocations?.fiscal_year?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FromBudgetLine</p>
<p>{budget_reallocations?.from_budget_line?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ToBudgetLine</p>
<p>{budget_reallocations?.to_budget_line?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Amount</p>
<p>{budget_reallocations?.amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{budget_reallocations?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{budget_reallocations?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RequestedBy</p>
<p>{budget_reallocations?.requested_by_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='RequestedAt'>
{budget_reallocations.requested_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={budget_reallocations.requested_at ?
new Date(
dayjs(budget_reallocations.requested_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No RequestedAt</p>}
</FormField>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={budget_reallocations?.justification} />
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/budget_reallocations/budget_reallocations-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/budget_reallocations/budget_reallocationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const BudgetReallocationsView = () => (
<EntityRecordViewPage
singularLabel="Budget Reallocation"
pluralLabel="Budget Reallocations"
stateKey="budget_reallocations"
recordKey="budget_reallocations"
fetchRecord={fetch}
listHref="/budget_reallocations/budget_reallocations-list"
editHref={(id) => `/budget_reallocations/budget_reallocations-edit/?id=${id ?? ''}`}
/>
);
BudgetReallocationsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_BUDGET_REALLOCATIONS'}>{page}</LayoutAuthenticated>;
};
Budget_reallocationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_BUDGET_REALLOCATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Budget_reallocationsView;
export default BudgetReallocationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,28 +400,14 @@ const EditCompliance_alertsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Compliance Alert"
pluralLabel="Compliance Alerts"
listHref="/compliance_alerts/compliance_alerts-list"
viewHref={`/compliance_alerts/compliance_alerts-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1057,6 +1044,7 @@ const EditCompliance_alertsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/compliance_alerts/compliance_alerts-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,713 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/compliance_alerts/compliance_alertsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Compliance_alertsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { compliance_alerts } = useAppSelector((state) => state.compliance_alerts)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View compliance_alerts')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View compliance_alerts')} main>
<BaseButton
color='info'
label='Edit'
href={`/compliance_alerts/compliance_alerts-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{compliance_alerts?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AlertType</p>
<p>{compliance_alerts?.alert_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Severity</p>
<p>{compliance_alerts?.severity ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Title</p>
<p>{compliance_alerts?.title}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Details</p>
{compliance_alerts.details
? <p dangerouslySetInnerHTML={{__html: compliance_alerts.details}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordType</p>
<p>{compliance_alerts?.record_type}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordKey</p>
<p>{compliance_alerts?.record_key}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{compliance_alerts?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AssignedTo</p>
<p>{compliance_alerts?.assigned_to_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='DetectedAt'>
{compliance_alerts.detected_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={compliance_alerts.detected_at ?
new Date(
dayjs(compliance_alerts.detected_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DetectedAt</p>}
</FormField>
<FormField label='DueAt'>
{compliance_alerts.due_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={compliance_alerts.due_at ?
new Date(
dayjs(compliance_alerts.due_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DueAt</p>}
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/compliance_alerts/compliance_alerts-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/compliance_alerts/compliance_alertsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ComplianceAlertsView = () => (
<EntityRecordViewPage
singularLabel="Compliance Alert"
pluralLabel="Compliance Alerts"
stateKey="compliance_alerts"
recordKey="compliance_alerts"
fetchRecord={fetch}
listHref="/compliance_alerts/compliance_alerts-list"
editHref={(id) => `/compliance_alerts/compliance_alerts-edit/?id=${id ?? ''}`}
/>
);
ComplianceAlertsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_COMPLIANCE_ALERTS'}>{page}</LayoutAuthenticated>;
};
Compliance_alertsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_COMPLIANCE_ALERTS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Compliance_alertsView;
export default ComplianceAlertsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditContract_amendmentsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Contract' labelFor='contract'>
<EnhancedEntityEditShell
entityLabel="Contract Amendment"
pluralLabel="Contract Amendments"
listHref="/contract_amendments/contract_amendments-list"
viewHref={`/contract_amendments/contract_amendments-view/?id=${id}`}
record={initialValues}
>
<FormField label='Contract' labelFor='contract'>
<Field
name='contract'
id='contract'
@ -916,6 +902,7 @@ const EditContract_amendmentsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/contract_amendments/contract_amendments-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,641 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/contract_amendments/contract_amendmentsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Contract_amendmentsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { contract_amendments } = useAppSelector((state) => state.contract_amendments)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View contract_amendments')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View contract_amendments')} main>
<BaseButton
color='info'
label='Edit'
href={`/contract_amendments/contract_amendments-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Contract</p>
<p>{contract_amendments?.contract?.contract_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AmendmentNumber</p>
<p>{contract_amendments?.amendment_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AmendmentType</p>
<p>{contract_amendments?.amendment_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ValueChangeAmount</p>
<p>{contract_amendments?.value_change_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DaysExtension</p>
<p>{contract_amendments?.days_extension || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Description</p>
{contract_amendments.description
? <p dangerouslySetInnerHTML={{__html: contract_amendments.description}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{contract_amendments?.status ?? 'No data'}</p>
</div>
<FormField label='EffectiveDate'>
{contract_amendments.effective_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={contract_amendments.effective_date ?
new Date(
dayjs(contract_amendments.effective_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EffectiveDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{contract_amendments?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/contract_amendments/contract_amendments-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/contract_amendments/contract_amendmentsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ContractAmendmentsView = () => (
<EntityRecordViewPage
singularLabel="Contract Amendment"
pluralLabel="Contract Amendments"
stateKey="contract_amendments"
recordKey="contract_amendments"
fetchRecord={fetch}
listHref="/contract_amendments/contract_amendments-list"
editHref={(id) => `/contract_amendments/contract_amendments-edit/?id=${id ?? ''}`}
/>
);
ContractAmendmentsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_CONTRACT_AMENDMENTS'}>{page}</LayoutAuthenticated>;
};
Contract_amendmentsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_CONTRACT_AMENDMENTS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Contract_amendmentsView;
export default ContractAmendmentsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -315,29 +316,14 @@ const EditContract_milestonesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Contract' labelFor='contract'>
<EnhancedEntityEditShell
entityLabel="Contract Milestone"
pluralLabel="Contract Milestones"
listHref="/contract_milestones/contract_milestones-list"
viewHref={`/contract_milestones/contract_milestones-view/?id=${id}`}
record={initialValues}
>
<FormField label='Contract' labelFor='contract'>
<Field
name='contract'
id='contract'
@ -851,6 +837,7 @@ const EditContract_milestonesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/contract_milestones/contract_milestones-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,617 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/contract_milestones/contract_milestonesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Contract_milestonesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { contract_milestones } = useAppSelector((state) => state.contract_milestones)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View contract_milestones')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View contract_milestones')} main>
<BaseButton
color='info'
label='Edit'
href={`/contract_milestones/contract_milestones-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Contract</p>
<p>{contract_milestones?.contract?.contract_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>MilestoneName</p>
<p>{contract_milestones?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DeliverableDescription</p>
{contract_milestones.deliverable_description
? <p dangerouslySetInnerHTML={{__html: contract_milestones.deliverable_description}}/>
: <p>No data</p>
}
</div>
<FormField label='DueDate'>
{contract_milestones.due_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={contract_milestones.due_date ?
new Date(
dayjs(contract_milestones.due_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DueDate</p>}
</FormField>
<FormField label='AcceptedAt'>
{contract_milestones.accepted_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={contract_milestones.accepted_at ?
new Date(
dayjs(contract_milestones.accepted_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No AcceptedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{contract_milestones?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PaymentPercent</p>
<p>{contract_milestones?.payment_percent || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{contract_milestones?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/contract_milestones/contract_milestones-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/contract_milestones/contract_milestonesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ContractMilestonesView = () => (
<EntityRecordViewPage
singularLabel="Contract Milestone"
pluralLabel="Contract Milestones"
stateKey="contract_milestones"
recordKey="contract_milestones"
fetchRecord={fetch}
listHref="/contract_milestones/contract_milestones-list"
editHref={(id) => `/contract_milestones/contract_milestones-edit/?id=${id ?? ''}`}
/>
);
ContractMilestonesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_CONTRACT_MILESTONES'}>{page}</LayoutAuthenticated>;
};
Contract_milestonesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_CONTRACT_MILESTONES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Contract_milestonesView;
export default ContractMilestonesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -539,28 +540,14 @@ const EditContractsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Contract"
pluralLabel="Contracts"
listHref="/contracts/contracts-list"
viewHref={`/contracts/contracts-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1707,6 +1694,7 @@ const EditContractsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/contracts/contracts-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -231,28 +232,14 @@ const EditDepartmentsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Department"
pluralLabel="Departments"
listHref="/departments/departments-list"
viewHref={`/departments/departments-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -636,6 +623,7 @@ const EditDepartmentsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/departments/departments-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,924 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/departments/departmentsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const DepartmentsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { departments } = useAppSelector((state) => state.departments)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View departments')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View departments')} main>
<BaseButton
color='info'
label='Edit'
href={`/departments/departments-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{departments?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DepartmentName</p>
<p>{departments?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DepartmentCode</p>
<p>{departments?.code}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ParentDepartment</p>
<p>{departments?.parent_department?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{departments?.status ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Approval_steps ApproverDepartment</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>StepOrder</th>
<th>StepName</th>
<th>MinimumAmount</th>
<th>MaximumAmount</th>
<th>RequiresComment</th>
</tr>
</thead>
<tbody>
{departments.approval_steps_approver_department && Array.isArray(departments.approval_steps_approver_department) &&
departments.approval_steps_approver_department.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/approval_steps/approval_steps-view/?id=${item.id}`)}>
<td data-label="step_order">
{ item.step_order }
</td>
<td data-label="name">
{ item.name }
</td>
<td data-label="min_amount">
{ item.min_amount }
</td>
<td data-label="max_amount">
{ item.max_amount }
</td>
<td data-label="requires_comment">
{ dataFormatter.booleanFormatter(item.requires_comment) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!departments?.approval_steps_approver_department?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Allocations Department</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>AllocationAmount</th>
<th>Currency</th>
<th>AllocatedAt</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{departments.allocations_department && Array.isArray(departments.allocations_department) &&
departments.allocations_department.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/allocations/allocations-view/?id=${item.id}`)}>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="allocated_at">
{ dataFormatter.dateTimeFormatter(item.allocated_at) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="notes">
{ item.notes }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!departments?.allocations_department?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Procurement_plans Department</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>PlanName</th>
<th>Status</th>
<th>EstimatedTotalAmount</th>
<th>Currency</th>
<th>SubmittedAt</th>
<th>ApprovedAt</th>
</tr>
</thead>
<tbody>
{departments.procurement_plans_department && Array.isArray(departments.procurement_plans_department) &&
departments.procurement_plans_department.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/procurement_plans/procurement_plans-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="estimated_total_amount">
{ item.estimated_total_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="approved_at">
{ dataFormatter.dateTimeFormatter(item.approved_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!departments?.procurement_plans_department?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Requisitions RequestingDepartment</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>RequisitionNumber</th>
<th>Title</th>
<th>ProcurementMethod</th>
<th>EstimatedAmount</th>
<th>Currency</th>
<th>NeededByDate</th>
<th>Status</th>
<th>SubmittedAt</th>
<th>RejectionReason</th>
</tr>
</thead>
<tbody>
{departments.requisitions_requesting_department && Array.isArray(departments.requisitions_requesting_department) &&
departments.requisitions_requesting_department.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/requisitions/requisitions-view/?id=${item.id}`)}>
<td data-label="requisition_number">
{ item.requisition_number }
</td>
<td data-label="title">
{ item.title }
</td>
<td data-label="procurement_method">
{ item.procurement_method }
</td>
<td data-label="estimated_amount">
{ item.estimated_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="needed_by_date">
{ dataFormatter.dateTimeFormatter(item.needed_by_date) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="rejection_reason">
{ item.rejection_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!departments?.requisitions_requesting_department?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/departments/departments-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/departments/departmentsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const DepartmentsView = () => (
<EntityRecordViewPage
singularLabel="Department"
pluralLabel="Departments"
stateKey="departments"
recordKey="departments"
fetchRecord={fetch}
listHref="/departments/departments-list"
editHref={(id) => `/departments/departments-edit/?id=${id ?? ''}`}
/>
);
DepartmentsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_DEPARTMENTS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_DEPARTMENTS'}>{page}</LayoutAuthenticated>;
};
export default DepartmentsView;
export default DepartmentsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,28 +400,14 @@ const EditDocumentsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Document"
pluralLabel="Documents"
listHref="/documents/documents-list"
viewHref={`/documents/documents-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1054,6 +1041,7 @@ const EditDocumentsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/documents/documents-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,710 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/documents/documentsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const DocumentsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { documents } = useAppSelector((state) => state.documents)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View documents')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View documents')} main>
<BaseButton
color='info'
label='Edit'
href={`/documents/documents-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{documents?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Category</p>
<p>{documents?.category ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Title</p>
<p>{documents?.title}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={documents?.description} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordType</p>
<p>{documents?.record_type}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordKey</p>
<p>{documents?.record_key}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>File</p>
{documents?.file?.length
? dataFormatter.filesFormatter(documents.file).map(link => (
<button
key={link.publicUrl}
onClick={(e) => saveFile(e, link.publicUrl, link.name)}
>
{link.name}
</button>
)) : <p>No File</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>VersionNumber</p>
<p>{documents?.version_number || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AccessLevel</p>
<p>{documents?.access_level ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>UploadedBy</p>
<p>{documents?.uploaded_by_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='UploadedAt'>
{documents.uploaded_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={documents.uploaded_at ?
new Date(
dayjs(documents.uploaded_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No UploadedAt</p>}
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/documents/documents-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/documents/documentsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const DocumentsView = () => (
<EntityRecordViewPage
singularLabel="Document"
pluralLabel="Documents"
stateKey="documents"
recordKey="documents"
fetchRecord={fetch}
listHref="/documents/documents-list"
editHref={(id) => `/documents/documents-edit/?id=${id ?? ''}`}
/>
);
DocumentsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_DOCUMENTS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_DOCUMENTS'}>{page}</LayoutAuthenticated>;
};
export default DocumentsView;
export default DocumentsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -231,28 +232,14 @@ const EditExpense_categoriesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Expense Category"
pluralLabel="Expense Categories"
listHref="/expense_categories/expense_categories-list"
viewHref={`/expense_categories/expense_categories-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -526,6 +513,7 @@ const EditExpense_categoriesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/expense_categories/expense_categories-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,546 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/expense_categories/expense_categoriesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Expense_categoriesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { expense_categories } = useAppSelector((state) => state.expense_categories)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View expense_categories')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View expense_categories')} main>
<BaseButton
color='info'
label='Edit'
href={`/expense_categories/expense_categories-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{expense_categories?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ExpenseCategory</p>
<p>{expense_categories?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Code</p>
<p>{expense_categories?.code}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={expense_categories?.description} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{expense_categories?.status ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Invoices ExpenseCategory</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>InvoiceNumber</th>
<th>InvoiceDate</th>
<th>ReceivedAt</th>
<th>DueDate</th>
<th>SubtotalAmount</th>
<th>TaxAmount</th>
<th>TotalAmount</th>
<th>Currency</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{expense_categories.invoices_expense_category && Array.isArray(expense_categories.invoices_expense_category) &&
expense_categories.invoices_expense_category.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/invoices/invoices-view/?id=${item.id}`)}>
<td data-label="invoice_number">
{ item.invoice_number }
</td>
<td data-label="invoice_date">
{ dataFormatter.dateTimeFormatter(item.invoice_date) }
</td>
<td data-label="received_at">
{ dataFormatter.dateTimeFormatter(item.received_at) }
</td>
<td data-label="due_date">
{ dataFormatter.dateTimeFormatter(item.due_date) }
</td>
<td data-label="subtotal_amount">
{ item.subtotal_amount }
</td>
<td data-label="tax_amount">
{ item.tax_amount }
</td>
<td data-label="total_amount">
{ item.total_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="notes">
{ item.notes }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!expense_categories?.invoices_expense_category?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/expense_categories/expense_categories-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/expense_categories/expense_categoriesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ExpenseCategoriesView = () => (
<EntityRecordViewPage
singularLabel="Expense Category"
pluralLabel="Expense Categories"
stateKey="expense_categories"
recordKey="expense_categories"
fetchRecord={fetch}
listHref="/expense_categories/expense_categories-list"
editHref={(id) => `/expense_categories/expense_categories-edit/?id=${id ?? ''}`}
/>
);
ExpenseCategoriesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_EXPENSE_CATEGORIES'}>{page}</LayoutAuthenticated>;
};
Expense_categoriesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_EXPENSE_CATEGORIES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Expense_categoriesView;
export default ExpenseCategoriesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,29 +372,14 @@ const EditField_verificationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Project' labelFor='project'>
<EnhancedEntityEditShell
entityLabel="Field Verification"
pluralLabel="Field Verifications"
listHref="/field_verifications/field_verifications-list"
viewHref={`/field_verifications/field_verifications-view/?id=${id}`}
record={initialValues}
>
<FormField label='Project' labelFor='project'>
<Field
name='project'
id='project'
@ -1088,6 +1074,7 @@ const EditField_verificationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/field_verifications/field_verifications-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,790 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/field_verifications/field_verificationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Field_verificationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { field_verifications } = useAppSelector((state) => state.field_verifications)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View field_verifications')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View field_verifications')} main>
<BaseButton
color='info'
label='Edit'
href={`/field_verifications/field_verifications-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Project</p>
<p>{field_verifications?.project?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>VerifiedBy</p>
<p>{field_verifications?.verified_by_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='VisitDate'>
{field_verifications.visit_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={field_verifications.visit_date ?
new Date(
dayjs(field_verifications.visit_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No VisitDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>VerificationType</p>
<p>{field_verifications?.verification_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Outcome</p>
<p>{field_verifications?.outcome ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Findings</p>
{field_verifications.findings
? <p dangerouslySetInnerHTML={{__html: field_verifications.findings}}/>
: <p>No data</p>
}
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={field_verifications?.actions_required} />
</FormField>
<FormField label='NextFollow-upAt'>
{field_verifications.next_followup_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={field_verifications.next_followup_at ?
new Date(
dayjs(field_verifications.next_followup_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No NextFollow-upAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Photos</p>
{field_verifications?.photos?.length
? (
<ImageField
name={'photos'}
image={field_verifications?.photos}
className='w-20 h-20'
/>
) : <p>No Photos</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{field_verifications?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/field_verifications/field_verifications-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/field_verifications/field_verificationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const FieldVerificationsView = () => (
<EntityRecordViewPage
singularLabel="Field Verification"
pluralLabel="Field Verifications"
stateKey="field_verifications"
recordKey="field_verifications"
fetchRecord={fetch}
listHref="/field_verifications/field_verifications-list"
editHref={(id) => `/field_verifications/field_verifications-edit/?id=${id ?? ''}`}
/>
);
FieldVerificationsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_FIELD_VERIFICATIONS'}>{page}</LayoutAuthenticated>;
};
Field_verificationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_FIELD_VERIFICATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Field_verificationsView;
export default FieldVerificationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -259,28 +260,14 @@ const EditFiscal_yearsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Fiscal Year"
pluralLabel="Fiscal Years"
listHref="/fiscal_years/fiscal_years-list"
viewHref={`/fiscal_years/fiscal_years-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -609,6 +596,7 @@ const EditFiscal_yearsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/fiscal_years/fiscal_years-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,964 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/fiscal_years/fiscal_yearsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Fiscal_yearsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { fiscal_years } = useAppSelector((state) => state.fiscal_years)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View fiscal_years')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View fiscal_years')} main>
<BaseButton
color='info'
label='Edit'
href={`/fiscal_years/fiscal_years-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{fiscal_years?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FiscalYear</p>
<p>{fiscal_years?.name}</p>
</div>
<FormField label='StartDate'>
{fiscal_years.start_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={fiscal_years.start_date ?
new Date(
dayjs(fiscal_years.start_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No StartDate</p>}
</FormField>
<FormField label='EndDate'>
{fiscal_years.end_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={fiscal_years.end_date ?
new Date(
dayjs(fiscal_years.end_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EndDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{fiscal_years?.status ?? 'No data'}</p>
</div>
<FormField label='IsCurrent'>
<SwitchField
field={{name: 'is_current', value: fiscal_years?.is_current}}
form={{setFieldValue: () => null}}
disabled
/>
</FormField>
<>
<p className={'block font-bold mb-2'}>Budget_programs FiscalYear</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ProgramName</th>
<th>ProgramCode</th>
<th>Objective</th>
<th>Status</th>
<th>ApprovedAmount</th>
<th>Currency</th>
</tr>
</thead>
<tbody>
{fiscal_years.budget_programs_fiscal_year && Array.isArray(fiscal_years.budget_programs_fiscal_year) &&
fiscal_years.budget_programs_fiscal_year.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/budget_programs/budget_programs-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="code">
{ item.code }
</td>
<td data-label="objective">
{ item.objective }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="approved_amount">
{ item.approved_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!fiscal_years?.budget_programs_fiscal_year?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Budget_reallocations FiscalYear</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>Amount</th>
<th>Currency</th>
<th>Status</th>
<th>RequestedAt</th>
<th>Justification</th>
</tr>
</thead>
<tbody>
{fiscal_years.budget_reallocations_fiscal_year && Array.isArray(fiscal_years.budget_reallocations_fiscal_year) &&
fiscal_years.budget_reallocations_fiscal_year.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/budget_reallocations/budget_reallocations-view/?id=${item.id}`)}>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="requested_at">
{ dataFormatter.dateTimeFormatter(item.requested_at) }
</td>
<td data-label="justification">
{ item.justification }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!fiscal_years?.budget_reallocations_fiscal_year?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Procurement_plans FiscalYear</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>PlanName</th>
<th>Status</th>
<th>EstimatedTotalAmount</th>
<th>Currency</th>
<th>SubmittedAt</th>
<th>ApprovedAt</th>
</tr>
</thead>
<tbody>
{fiscal_years.procurement_plans_fiscal_year && Array.isArray(fiscal_years.procurement_plans_fiscal_year) &&
fiscal_years.procurement_plans_fiscal_year.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/procurement_plans/procurement_plans-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="estimated_total_amount">
{ item.estimated_total_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="approved_at">
{ dataFormatter.dateTimeFormatter(item.approved_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!fiscal_years?.procurement_plans_fiscal_year?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Programs FiscalYear</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ProgramName</th>
<th>ProgramCode</th>
<th>Status</th>
<th>BudgetAmount</th>
<th>Currency</th>
</tr>
</thead>
<tbody>
{fiscal_years.programs_fiscal_year && Array.isArray(fiscal_years.programs_fiscal_year) &&
fiscal_years.programs_fiscal_year.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/programs/programs-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="code">
{ item.code }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="budget_amount">
{ item.budget_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!fiscal_years?.programs_fiscal_year?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Ledger_entries FiscalYear</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>EntryReference</th>
<th>EntryDate</th>
<th>EntryType</th>
<th>Currency</th>
<th>DebitAmount</th>
<th>CreditAmount</th>
<th>Description</th>
<th>RecordType</th>
<th>RecordKey</th>
</tr>
</thead>
<tbody>
{fiscal_years.ledger_entries_fiscal_year && Array.isArray(fiscal_years.ledger_entries_fiscal_year) &&
fiscal_years.ledger_entries_fiscal_year.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/ledger_entries/ledger_entries-view/?id=${item.id}`)}>
<td data-label="entry_reference">
{ item.entry_reference }
</td>
<td data-label="entry_date">
{ dataFormatter.dateTimeFormatter(item.entry_date) }
</td>
<td data-label="entry_type">
{ item.entry_type }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="debit_amount">
{ item.debit_amount }
</td>
<td data-label="credit_amount">
{ item.credit_amount }
</td>
<td data-label="description">
{ item.description }
</td>
<td data-label="record_type">
{ item.record_type }
</td>
<td data-label="record_key">
{ item.record_key }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!fiscal_years?.ledger_entries_fiscal_year?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/fiscal_years/fiscal_years-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/fiscal_years/fiscal_yearsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const FiscalYearsView = () => (
<EntityRecordViewPage
singularLabel="Fiscal Year"
pluralLabel="Fiscal Years"
stateKey="fiscal_years"
recordKey="fiscal_years"
fetchRecord={fetch}
listHref="/fiscal_years/fiscal_years-list"
editHref={(id) => `/fiscal_years/fiscal_years-edit/?id=${id ?? ''}`}
/>
);
FiscalYearsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_FISCAL_YEARS'}>{page}</LayoutAuthenticated>;
};
Fiscal_yearsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_FISCAL_YEARS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Fiscal_yearsView;
export default FiscalYearsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -315,28 +316,14 @@ const EditFunding_sourcesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Funding Source"
pluralLabel="Funding Sources"
listHref="/funding_sources/funding_sources-list"
viewHref={`/funding_sources/funding_sources-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -741,6 +728,7 @@ const EditFunding_sourcesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/funding_sources/funding_sources-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,696 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/funding_sources/funding_sourcesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Funding_sourcesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { funding_sources } = useAppSelector((state) => state.funding_sources)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View funding_sources')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View funding_sources')} main>
<BaseButton
color='info'
label='Edit'
href={`/funding_sources/funding_sources-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{funding_sources?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FundingSourceName</p>
<p>{funding_sources?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>SourceType</p>
<p>{funding_sources?.source_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ReferenceCode</p>
<p>{funding_sources?.reference_code}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{funding_sources?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TotalCommittedAmount</p>
<p>{funding_sources?.total_committed_amount || 'No data'}</p>
</div>
<FormField label='EffectiveDate'>
{funding_sources.effective_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={funding_sources.effective_date ?
new Date(
dayjs(funding_sources.effective_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EffectiveDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{funding_sources?.status ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Budget_programs FundingSource</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ProgramName</th>
<th>ProgramCode</th>
<th>Objective</th>
<th>Status</th>
<th>ApprovedAmount</th>
<th>Currency</th>
</tr>
</thead>
<tbody>
{funding_sources.budget_programs_funding_source && Array.isArray(funding_sources.budget_programs_funding_source) &&
funding_sources.budget_programs_funding_source.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/budget_programs/budget_programs-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="code">
{ item.code }
</td>
<td data-label="objective">
{ item.objective }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="approved_amount">
{ item.approved_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!funding_sources?.budget_programs_funding_source?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Programs FundingSource</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ProgramName</th>
<th>ProgramCode</th>
<th>Status</th>
<th>BudgetAmount</th>
<th>Currency</th>
</tr>
</thead>
<tbody>
{funding_sources.programs_funding_source && Array.isArray(funding_sources.programs_funding_source) &&
funding_sources.programs_funding_source.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/programs/programs-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="code">
{ item.code }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="budget_amount">
{ item.budget_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!funding_sources?.programs_funding_source?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/funding_sources/funding_sources-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/funding_sources/funding_sourcesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const FundingSourcesView = () => (
<EntityRecordViewPage
singularLabel="Funding Source"
pluralLabel="Funding Sources"
stateKey="funding_sources"
recordKey="funding_sources"
fetchRecord={fetch}
listHref="/funding_sources/funding_sources-list"
editHref={(id) => `/funding_sources/funding_sources-edit/?id=${id ?? ''}`}
/>
);
FundingSourcesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_FUNDING_SOURCES'}>{page}</LayoutAuthenticated>;
};
Funding_sourcesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_FUNDING_SOURCES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Funding_sourcesView;
export default FundingSourcesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditGrant_applicationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Grant' labelFor='grant'>
<EnhancedEntityEditShell
entityLabel="Grant Application"
pluralLabel="Grant Applications"
listHref="/grant_applications/grant_applications-list"
viewHref={`/grant_applications/grant_applications-view/?id=${id}`}
record={initialValues}
>
<FormField label='Grant' labelFor='grant'>
<Field
name='grant'
id='grant'
@ -1020,6 +1006,7 @@ const EditGrant_applicationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/grant_applications/grant_applications-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,919 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/grant_applications/grant_applicationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Grant_applicationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { grant_applications } = useAppSelector((state) => state.grant_applications)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View grant_applications')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View grant_applications')} main>
<BaseButton
color='info'
label='Edit'
href={`/grant_applications/grant_applications-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Grant</p>
<p>{grant_applications?.grant?.call_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Beneficiary</p>
<p>{grant_applications?.beneficiary?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ApplicationReference</p>
<p>{grant_applications?.application_reference}</p>
</div>
<FormField label='SubmittedAt'>
{grant_applications.submitted_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grant_applications.submitted_at ?
new Date(
dayjs(grant_applications.submitted_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No SubmittedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RequestedAmount</p>
<p>{grant_applications?.requested_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{grant_applications?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ProposalSummary</p>
{grant_applications.proposal_summary
? <p dangerouslySetInnerHTML={{__html: grant_applications.proposal_summary}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{grant_applications?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{grant_applications?.organizations?.name ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Grant_evaluations Application</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>Score</th>
<th>Comments</th>
<th>Recommendation</th>
<th>EvaluatedAt</th>
</tr>
</thead>
<tbody>
{grant_applications.grant_evaluations_application && Array.isArray(grant_applications.grant_evaluations_application) &&
grant_applications.grant_evaluations_application.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/grant_evaluations/grant_evaluations-view/?id=${item.id}`)}>
<td data-label="score">
{ item.score }
</td>
<td data-label="comments">
{ item.comments }
</td>
<td data-label="recommendation">
{ item.recommendation }
</td>
<td data-label="evaluated_at">
{ dataFormatter.dateTimeFormatter(item.evaluated_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!grant_applications?.grant_evaluations_application?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Grant_tranches Application</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>TrancheNumber</th>
<th>Amount</th>
<th>Currency</th>
<th>PlannedDisbursementAt</th>
<th>DisbursedAt</th>
<th>Status</th>
<th>Conditions</th>
</tr>
</thead>
<tbody>
{grant_applications.grant_tranches_application && Array.isArray(grant_applications.grant_tranches_application) &&
grant_applications.grant_tranches_application.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/grant_tranches/grant_tranches-view/?id=${item.id}`)}>
<td data-label="tranche_number">
{ item.tranche_number }
</td>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="planned_disbursement_at">
{ dataFormatter.dateTimeFormatter(item.planned_disbursement_at) }
</td>
<td data-label="disbursed_at">
{ dataFormatter.dateTimeFormatter(item.disbursed_at) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="conditions">
{ item.conditions }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!grant_applications?.grant_tranches_application?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/grant_applications/grant_applications-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/grant_applications/grant_applicationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const GrantApplicationsView = () => (
<EntityRecordViewPage
singularLabel="Grant Application"
pluralLabel="Grant Applications"
stateKey="grant_applications"
recordKey="grant_applications"
fetchRecord={fetch}
listHref="/grant_applications/grant_applications-list"
editHref={(id) => `/grant_applications/grant_applications-edit/?id=${id ?? ''}`}
/>
);
GrantApplicationsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_GRANT_APPLICATIONS'}>{page}</LayoutAuthenticated>;
};
Grant_applicationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_GRANT_APPLICATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Grant_applicationsView;
export default GrantApplicationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -287,29 +288,14 @@ const EditGrant_evaluationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Application' labelFor='application'>
<EnhancedEntityEditShell
entityLabel="Grant Evaluation"
pluralLabel="Grant Evaluations"
listHref="/grant_evaluations/grant_evaluations-list"
viewHref={`/grant_evaluations/grant_evaluations-view/?id=${id}`}
record={initialValues}
>
<FormField label='Application' labelFor='application'>
<Field
name='application'
id='application'
@ -875,6 +861,7 @@ const EditGrant_evaluationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/grant_evaluations/grant_evaluations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,675 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/grant_evaluations/grant_evaluationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Grant_evaluationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { grant_evaluations } = useAppSelector((state) => state.grant_evaluations)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View grant_evaluations')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View grant_evaluations')} main>
<BaseButton
color='info'
label='Edit'
href={`/grant_evaluations/grant_evaluations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Application</p>
<p>{grant_evaluations?.application?.application_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Evaluator</p>
<p>{grant_evaluations?.evaluator_user?.firstName ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Score</p>
<p>{grant_evaluations?.score || 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={grant_evaluations?.comments} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Recommendation</p>
<p>{grant_evaluations?.recommendation ?? 'No data'}</p>
</div>
<FormField label='EvaluatedAt'>
{grant_evaluations.evaluated_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grant_evaluations.evaluated_at ?
new Date(
dayjs(grant_evaluations.evaluated_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EvaluatedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{grant_evaluations?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/grant_evaluations/grant_evaluations-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/grant_evaluations/grant_evaluationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const GrantEvaluationsView = () => (
<EntityRecordViewPage
singularLabel="Grant Evaluation"
pluralLabel="Grant Evaluations"
stateKey="grant_evaluations"
recordKey="grant_evaluations"
fetchRecord={fetch}
listHref="/grant_evaluations/grant_evaluations-list"
editHref={(id) => `/grant_evaluations/grant_evaluations-edit/?id=${id ?? ''}`}
/>
);
GrantEvaluationsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_GRANT_EVALUATIONS'}>{page}</LayoutAuthenticated>;
};
Grant_evaluationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_GRANT_EVALUATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Grant_evaluationsView;
export default GrantEvaluationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditGrant_tranchesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Application' labelFor='application'>
<EnhancedEntityEditShell
entityLabel="Grant Tranche"
pluralLabel="Grant Tranches"
listHref="/grant_tranches/grant_tranches-list"
viewHref={`/grant_tranches/grant_tranches-view/?id=${id}`}
record={initialValues}
>
<FormField label='Application' labelFor='application'>
<Field
name='application'
id='application'
@ -914,6 +900,7 @@ const EditGrant_tranchesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/grant_tranches/grant_tranches-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,645 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/grant_tranches/grant_tranchesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Grant_tranchesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { grant_tranches } = useAppSelector((state) => state.grant_tranches)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View grant_tranches')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View grant_tranches')} main>
<BaseButton
color='info'
label='Edit'
href={`/grant_tranches/grant_tranches-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Application</p>
<p>{grant_tranches?.application?.application_reference ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TrancheNumber</p>
<p>{grant_tranches?.tranche_number || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Amount</p>
<p>{grant_tranches?.amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{grant_tranches?.currency ?? 'No data'}</p>
</div>
<FormField label='PlannedDisbursementAt'>
{grant_tranches.planned_disbursement_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grant_tranches.planned_disbursement_at ?
new Date(
dayjs(grant_tranches.planned_disbursement_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No PlannedDisbursementAt</p>}
</FormField>
<FormField label='DisbursedAt'>
{grant_tranches.disbursed_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grant_tranches.disbursed_at ?
new Date(
dayjs(grant_tranches.disbursed_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DisbursedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{grant_tranches?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={grant_tranches?.conditions} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{grant_tranches?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/grant_tranches/grant_tranches-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/grant_tranches/grant_tranchesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const GrantTranchesView = () => (
<EntityRecordViewPage
singularLabel="Grant Tranche"
pluralLabel="Grant Tranches"
stateKey="grant_tranches"
recordKey="grant_tranches"
fetchRecord={fetch}
listHref="/grant_tranches/grant_tranches-list"
editHref={(id) => `/grant_tranches/grant_tranches-edit/?id=${id ?? ''}`}
/>
);
GrantTranchesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_GRANT_TRANCHES'}>{page}</LayoutAuthenticated>;
};
Grant_tranchesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_GRANT_TRANCHES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Grant_tranchesView;
export default GrantTranchesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,28 +400,14 @@ const EditGrantsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Grant"
pluralLabel="Grants"
listHref="/grants/grants-list"
viewHref={`/grants/grants-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1046,6 +1033,7 @@ const EditGrantsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/grants/grants-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,926 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/grants/grantsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const GrantsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { grants } = useAppSelector((state) => state.grants)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View grants')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View grants')} main>
<BaseButton
color='info'
label='Edit'
href={`/grants/grants-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{grants?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Program</p>
<p>{grants?.program?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FundingWindowName</p>
<p>{grants?.funding_window_name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>CallReference</p>
<p>{grants?.call_reference}</p>
</div>
<FormField label='CallOpenAt'>
{grants.call_open_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grants.call_open_at ?
new Date(
dayjs(grants.call_open_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No CallOpenAt</p>}
</FormField>
<FormField label='CallCloseAt'>
{grants.call_close_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={grants.call_close_at ?
new Date(
dayjs(grants.call_close_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No CallCloseAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{grants?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>EligibilityRules</p>
{grants.eligibility_rules
? <p dangerouslySetInnerHTML={{__html: grants.eligibility_rules}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TotalEnvelopeAmount</p>
<p>{grants?.total_envelope_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{grants?.currency ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={grants?.notes} />
</FormField>
<>
<p className={'block font-bold mb-2'}>Beneficiaries Grant</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>BeneficiaryName</th>
<th>BeneficiaryType</th>
<th>RegistrationNumber</th>
<th>ContactEmail</th>
<th>ContactPhone</th>
<th>ApprovedAmount</th>
<th>Currency</th>
<th>Status</th>
<th>ApprovedAt</th>
</tr>
</thead>
<tbody>
{grants.beneficiaries_grant && Array.isArray(grants.beneficiaries_grant) &&
grants.beneficiaries_grant.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/beneficiaries/beneficiaries-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="beneficiary_type">
{ item.beneficiary_type }
</td>
<td data-label="registration_number">
{ item.registration_number }
</td>
<td data-label="contact_email">
{ item.contact_email }
</td>
<td data-label="contact_phone">
{ item.contact_phone }
</td>
<td data-label="approved_amount">
{ item.approved_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="approved_at">
{ dataFormatter.dateTimeFormatter(item.approved_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!grants?.beneficiaries_grant?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Grant_applications Grant</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ApplicationReference</th>
<th>SubmittedAt</th>
<th>RequestedAmount</th>
<th>Currency</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{grants.grant_applications_grant && Array.isArray(grants.grant_applications_grant) &&
grants.grant_applications_grant.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/grant_applications/grant_applications-view/?id=${item.id}`)}>
<td data-label="application_reference">
{ item.application_reference }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="requested_amount">
{ item.requested_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!grants?.grant_applications_grant?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/grants/grants-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/grants/grantsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const GrantsView = () => (
<EntityRecordViewPage
singularLabel="Grant"
pluralLabel="Grants"
stateKey="grants"
recordKey="grants"
fetchRecord={fetch}
listHref="/grants/grants-list"
editHref={(id) => `/grants/grants-edit/?id=${id ?? ''}`}
/>
);
GrantsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_GRANTS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_GRANTS'}>{page}</LayoutAuthenticated>;
};
export default GrantsView;
export default GrantsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -511,28 +512,14 @@ const EditInvoicesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Invoice"
pluralLabel="Invoices"
listHref="/invoices/invoices-list"
viewHref={`/invoices/invoices-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1628,6 +1615,7 @@ const EditInvoicesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/invoices/invoices-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,29 +372,14 @@ const EditIssuesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Project' labelFor='project'>
<EnhancedEntityEditShell
entityLabel="Issue"
pluralLabel="Issues"
listHref="/issues/issues-list"
viewHref={`/issues/issues-view/?id=${id}`}
record={initialValues}
>
<FormField label='Project' labelFor='project'>
<Field
name='project'
id='project'
@ -1094,6 +1080,7 @@ const EditIssuesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/issues/issues-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,791 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/issues/issuesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const IssuesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { issues } = useAppSelector((state) => state.issues)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View issues')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View issues')} main>
<BaseButton
color='info'
label='Edit'
href={`/issues/issues-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Project</p>
<p>{issues?.project?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>IssueTitle</p>
<p>{issues?.title}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Description</p>
{issues.description
? <p dangerouslySetInnerHTML={{__html: issues.description}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Severity</p>
<p>{issues?.severity ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{issues?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>AssignedTo</p>
<p>{issues?.assigned_to_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='OpenedAt'>
{issues.opened_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={issues.opened_at ?
new Date(
dayjs(issues.opened_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No OpenedAt</p>}
</FormField>
<FormField label='DueAt'>
{issues.due_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={issues.due_at ?
new Date(
dayjs(issues.due_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No DueAt</p>}
</FormField>
<FormField label='ResolvedAt'>
{issues.resolved_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={issues.resolved_at ?
new Date(
dayjs(issues.resolved_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ResolvedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{issues?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/issues/issues-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/issues/issuesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const IssuesView = () => (
<EntityRecordViewPage
singularLabel="Issue"
pluralLabel="Issues"
stateKey="issues"
recordKey="issues"
fetchRecord={fetch}
listHref="/issues/issues-list"
editHref={(id) => `/issues/issues-edit/?id=${id ?? ''}`}
/>
);
IssuesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_ISSUES'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_ISSUES'}>{page}</LayoutAuthenticated>;
};
export default IssuesView;
export default IssuesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,28 +400,14 @@ const EditLedger_entriesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Ledger Entry"
pluralLabel="Ledger Entries"
listHref="/ledger_entries/ledger_entries-list"
viewHref={`/ledger_entries/ledger_entries-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1038,6 +1025,7 @@ const EditLedger_entriesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/ledger_entries/ledger_entries-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,701 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/ledger_entries/ledger_entriesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Ledger_entriesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { ledger_entries } = useAppSelector((state) => state.ledger_entries)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View ledger_entries')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View ledger_entries')} main>
<BaseButton
color='info'
label='Edit'
href={`/ledger_entries/ledger_entries-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{ledger_entries?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FiscalYear</p>
<p>{ledger_entries?.fiscal_year?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>EntryReference</p>
<p>{ledger_entries?.entry_reference}</p>
</div>
<FormField label='EntryDate'>
{ledger_entries.entry_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={ledger_entries.entry_date ?
new Date(
dayjs(ledger_entries.entry_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No EntryDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>EntryType</p>
<p>{ledger_entries?.entry_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{ledger_entries?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DebitAmount</p>
<p>{ledger_entries?.debit_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>CreditAmount</p>
<p>{ledger_entries?.credit_amount || 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={ledger_entries?.description} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordType</p>
<p>{ledger_entries?.record_type}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordKey</p>
<p>{ledger_entries?.record_key}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/ledger_entries/ledger_entries-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/ledger_entries/ledger_entriesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const LedgerEntriesView = () => (
<EntityRecordViewPage
singularLabel="Ledger Entry"
pluralLabel="Ledger Entries"
stateKey="ledger_entries"
recordKey="ledger_entries"
fetchRecord={fetch}
listHref="/ledger_entries/ledger_entries-list"
editHref={(id) => `/ledger_entries/ledger_entries-edit/?id=${id ?? ''}`}
/>
);
LedgerEntriesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_LEDGER_ENTRIES'}>{page}</LayoutAuthenticated>;
};
Ledger_entriesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_LEDGER_ENTRIES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Ledger_entriesView;
export default LedgerEntriesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditNotificationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Notification"
pluralLabel="Notifications"
listHref="/notifications/notifications-list"
viewHref={`/notifications/notifications-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -910,6 +897,7 @@ const EditNotificationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/notifications/notifications-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,640 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/notifications/notificationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const NotificationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { notifications } = useAppSelector((state) => state.notifications)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View notifications')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View notifications')} main>
<BaseButton
color='info'
label='Edit'
href={`/notifications/notifications-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{notifications?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>User</p>
<p>{notifications?.user?.firstName ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Type</p>
<p>{notifications?.type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Title</p>
<p>{notifications?.title}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={notifications?.message} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordType</p>
<p>{notifications?.record_type}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RecordKey</p>
<p>{notifications?.record_key}</p>
</div>
<FormField label='Read'>
<SwitchField
field={{name: 'read', value: notifications?.read}}
form={{setFieldValue: () => null}}
disabled
/>
</FormField>
<FormField label='SentAt'>
{notifications.sent_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={notifications.sent_at ?
new Date(
dayjs(notifications.sent_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No SentAt</p>}
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/notifications/notifications-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/notifications/notificationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const NotificationsView = () => (
<EntityRecordViewPage
singularLabel="Notification"
pluralLabel="Notifications"
stateKey="notifications"
recordKey="notifications"
fetchRecord={fetch}
listHref="/notifications/notifications-list"
editHref={(id) => `/notifications/notifications-edit/?id=${id ?? ''}`}
/>
);
NotificationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_NOTIFICATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_NOTIFICATIONS'}>{page}</LayoutAuthenticated>;
};
export default NotificationsView;
export default NotificationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,28 +372,14 @@ const EditObligationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Obligation"
pluralLabel="Obligations"
listHref="/obligations/obligations-list"
viewHref={`/obligations/obligations-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1178,6 +1165,7 @@ const EditObligationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/obligations/obligations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,873 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/obligations/obligationsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const ObligationsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { obligations } = useAppSelector((state) => state.obligations)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View obligations')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View obligations')} main>
<BaseButton
color='info'
label='Edit'
href={`/obligations/obligations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{obligations?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BudgetLine</p>
<p>{obligations?.budget_line?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Contract</p>
<p>{obligations?.contract?.contract_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Project</p>
<p>{obligations?.project?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ObligationNumber</p>
<p>{obligations?.obligation_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Amount</p>
<p>{obligations?.amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{obligations?.currency ?? 'No data'}</p>
</div>
<FormField label='ObligatedAt'>
{obligations.obligated_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={obligations.obligated_at ?
new Date(
dayjs(obligations.obligated_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ObligatedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{obligations?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={obligations?.notes} />
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/obligations/obligations-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/obligations/obligationsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ObligationsView = () => (
<EntityRecordViewPage
singularLabel="Obligation"
pluralLabel="Obligations"
stateKey="obligations"
recordKey="obligations"
fetchRecord={fetch}
listHref="/obligations/obligations-list"
editHref={(id) => `/obligations/obligations-edit/?id=${id ?? ''}`}
/>
);
ObligationsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_OBLIGATIONS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_OBLIGATIONS'}>{page}</LayoutAuthenticated>;
};
export default ObligationsView;
export default ObligationsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -119,10 +120,14 @@ const EditOrganizationsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField
<EnhancedEntityEditShell
entityLabel="Organization"
pluralLabel="Organizations"
listHref="/organizations/organizations-list"
viewHref={`/organizations/organizations-view/?id=${id}`}
record={initialValues}
>
<FormField
label="Name"
>
<Field
@ -165,6 +170,7 @@ const EditOrganizationsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/organizations/organizations-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -315,28 +316,14 @@ const EditPayment_batchesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Payment Batch"
pluralLabel="Payment Batchs"
listHref="/payment_batches/payment_batches-list"
viewHref={`/payment_batches/payment_batches-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -853,6 +840,7 @@ const EditPayment_batchesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/payment_batches/payment_batches-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,717 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/payment_batches/payment_batchesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Payment_batchesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { payment_batches } = useAppSelector((state) => state.payment_batches)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View payment_batches')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View payment_batches')} main>
<BaseButton
color='info'
label='Edit'
href={`/payment_batches/payment_batches-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{payment_batches?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>BatchNumber</p>
<p>{payment_batches?.batch_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{payment_batches?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{payment_batches?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TotalAmount</p>
<p>{payment_batches?.total_amount || 'No data'}</p>
</div>
<FormField label='ScheduledAt'>
{payment_batches.scheduled_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={payment_batches.scheduled_at ?
new Date(
dayjs(payment_batches.scheduled_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ScheduledAt</p>}
</FormField>
<FormField label='ProcessedAt'>
{payment_batches.processed_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={payment_batches.processed_at ?
new Date(
dayjs(payment_batches.processed_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ProcessedAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PreparedBy</p>
<p>{payment_batches?.prepared_by_user?.firstName ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Payments PaymentBatch</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>PaymentReference</th>
<th>PaymentDate</th>
<th>Amount</th>
<th>Currency</th>
<th>Status</th>
<th>FailureReason</th>
</tr>
</thead>
<tbody>
{payment_batches.payments_batch && Array.isArray(payment_batches.payments_batch) &&
payment_batches.payments_batch.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/payments/payments-view/?id=${item.id}`)}>
<td data-label="payment_reference">
{ item.payment_reference }
</td>
<td data-label="payment_date">
{ dataFormatter.dateTimeFormatter(item.payment_date) }
</td>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="failure_reason">
{ item.failure_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!payment_batches?.payments_batch?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/payment_batches/payment_batches-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/payment_batches/payment_batchesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const PaymentBatchesView = () => (
<EntityRecordViewPage
singularLabel="Payment Batch"
pluralLabel="Payment Batchs"
stateKey="payment_batches"
recordKey="payment_batches"
fetchRecord={fetch}
listHref="/payment_batches/payment_batches-list"
editHref={(id) => `/payment_batches/payment_batches-edit/?id=${id ?? ''}`}
/>
);
PaymentBatchesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_PAYMENT_BATCHES'}>{page}</LayoutAuthenticated>;
};
Payment_batchesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PAYMENT_BATCHES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Payment_batchesView;
export default PaymentBatchesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,28 +372,14 @@ const EditPayment_requestsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Payment Request"
pluralLabel="Payment Requests"
listHref="/payment_requests/payment_requests-list"
viewHref={`/payment_requests/payment_requests-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1086,6 +1073,7 @@ const EditPayment_requestsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/payment_requests/payment_requests-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,874 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/payment_requests/payment_requestsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Payment_requestsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { payment_requests } = useAppSelector((state) => state.payment_requests)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View payment_requests')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View payment_requests')} main>
<BaseButton
color='info'
label='Edit'
href={`/payment_requests/payment_requests-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{payment_requests?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Invoice</p>
<p>{payment_requests?.invoice?.invoice_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RequestNumber</p>
<p>{payment_requests?.request_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RequestedAmount</p>
<p>{payment_requests?.requested_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{payment_requests?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PaymentMethod</p>
<p>{payment_requests?.payment_method ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{payment_requests?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RequestedBy</p>
<p>{payment_requests?.requested_by_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='RequestedAt'>
{payment_requests.requested_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={payment_requests.requested_at ?
new Date(
dayjs(payment_requests.requested_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No RequestedAt</p>}
</FormField>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={payment_requests?.justification} />
</FormField>
<>
<p className={'block font-bold mb-2'}>Payments PaymentRequest</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>PaymentReference</th>
<th>PaymentDate</th>
<th>Amount</th>
<th>Currency</th>
<th>Status</th>
<th>FailureReason</th>
</tr>
</thead>
<tbody>
{payment_requests.payments_payment_request && Array.isArray(payment_requests.payments_payment_request) &&
payment_requests.payments_payment_request.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/payments/payments-view/?id=${item.id}`)}>
<td data-label="payment_reference">
{ item.payment_reference }
</td>
<td data-label="payment_date">
{ dataFormatter.dateTimeFormatter(item.payment_date) }
</td>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="failure_reason">
{ item.failure_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!payment_requests?.payments_payment_request?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/payment_requests/payment_requests-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/payment_requests/payment_requestsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const PaymentRequestsView = () => (
<EntityRecordViewPage
singularLabel="Payment Request"
pluralLabel="Payment Requests"
stateKey="payment_requests"
recordKey="payment_requests"
fetchRecord={fetch}
listHref="/payment_requests/payment_requests-list"
editHref={(id) => `/payment_requests/payment_requests-edit/?id=${id ?? ''}`}
/>
);
PaymentRequestsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_PAYMENT_REQUESTS'}>{page}</LayoutAuthenticated>;
};
Payment_requestsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PAYMENT_REQUESTS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Payment_requestsView;
export default PaymentRequestsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -371,28 +372,14 @@ const EditPaymentsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Payment"
pluralLabel="Payments"
listHref="/payments/payments-list"
viewHref={`/payments/payments-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1178,6 +1165,7 @@ const EditPaymentsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/payments/payments-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,873 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/payments/paymentsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const PaymentsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { payments } = useAppSelector((state) => state.payments)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View payments')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View payments')} main>
<BaseButton
color='info'
label='Edit'
href={`/payments/payments-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{payments?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PaymentRequest</p>
<p>{payments?.payment_request?.request_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PaymentBatch</p>
<p>{payments?.batch?.batch_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Vendor</p>
<p>{payments?.vendor?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PaymentReference</p>
<p>{payments?.payment_reference}</p>
</div>
<FormField label='PaymentDate'>
{payments.payment_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={payments.payment_date ?
new Date(
dayjs(payments.payment_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No PaymentDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Amount</p>
<p>{payments?.amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{payments?.currency ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{payments?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={payments?.failure_reason} />
</FormField>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/payments/payments-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/payments/paymentsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const PaymentsView = () => (
<EntityRecordViewPage
singularLabel="Payment"
pluralLabel="Payments"
stateKey="payments"
recordKey="payments"
fetchRecord={fetch}
listHref="/payments/payments-list"
editHref={(id) => `/payments/payments-edit/?id=${id ?? ''}`}
/>
);
PaymentsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PAYMENTS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_PAYMENTS'}>{page}</LayoutAuthenticated>;
};
export default PaymentsView;
export default PaymentsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -119,10 +120,14 @@ const EditPermissionsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField
<EnhancedEntityEditShell
entityLabel="Permission"
pluralLabel="Permissions"
listHref="/permissions/permissions-list"
viewHref={`/permissions/permissions-view/?id=${id}`}
record={initialValues}
>
<FormField
label="Name"
>
<Field
@ -165,6 +170,7 @@ const EditPermissionsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/permissions/permissions-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,205 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/permissions/permissionsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/permissions/permissionsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
import {hasPermission} from "../../helpers/userPermissions";
const PermissionsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { permissions } = useAppSelector((state) => state.permissions)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View permissions')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View permissions')} main>
<BaseButton
color='info'
label='Edit'
href={`/permissions/permissions-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Name</p>
<p>{permissions?.name}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Role_permissions Permission</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
</tr>
</thead>
<tbody>
{permissions.role_permissions_permission && Array.isArray(permissions.role_permissions_permission) &&
permissions.role_permissions_permission.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/role_permissions/role_permissions-view/?id=${item.id}`)}>
</tr>
))}
</tbody>
</table>
</div>
{!permissions?.role_permissions_permission?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/permissions/permissions-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
const PermissionsView = () => (
<EntityRecordViewPage
singularLabel="Permission"
pluralLabel="Permissions"
stateKey="permissions"
recordKey="permissions"
fetchRecord={fetch}
listHref="/permissions/permissions-list"
editHref={(id) => `/permissions/permissions-edit/?id=${id ?? ''}`}
/>
);
PermissionsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PERMISSIONS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_PERMISSIONS'}>{page}</LayoutAuthenticated>;
};
export default PermissionsView;
export default PermissionsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditProcurement_plansPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Procurement Plan"
pluralLabel="Procurement Plans"
listHref="/procurement_plans/procurement_plans-list"
viewHref={`/procurement_plans/procurement_plans-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1021,6 +1008,7 @@ const EditProcurement_plansPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/procurement_plans/procurement_plans-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,893 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/procurement_plans/procurement_plansSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Procurement_plansView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { procurement_plans } = useAppSelector((state) => state.procurement_plans)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View procurement_plans')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View procurement_plans')} main>
<BaseButton
color='info'
label='Edit'
href={`/procurement_plans/procurement_plans-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{procurement_plans?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>FiscalYear</p>
<p>{procurement_plans?.fiscal_year?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Department</p>
<p>{procurement_plans?.department?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>PlanName</p>
<p>{procurement_plans?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{procurement_plans?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>EstimatedTotalAmount</p>
<p>{procurement_plans?.estimated_total_amount || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Currency</p>
<p>{procurement_plans?.currency ?? 'No data'}</p>
</div>
<FormField label='SubmittedAt'>
{procurement_plans.submitted_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={procurement_plans.submitted_at ?
new Date(
dayjs(procurement_plans.submitted_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No SubmittedAt</p>}
</FormField>
<FormField label='ApprovedAt'>
{procurement_plans.approved_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={procurement_plans.approved_at ?
new Date(
dayjs(procurement_plans.approved_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ApprovedAt</p>}
</FormField>
<>
<p className={'block font-bold mb-2'}>Requisitions ProcurementPlan</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>RequisitionNumber</th>
<th>Title</th>
<th>ProcurementMethod</th>
<th>EstimatedAmount</th>
<th>Currency</th>
<th>NeededByDate</th>
<th>Status</th>
<th>SubmittedAt</th>
<th>RejectionReason</th>
</tr>
</thead>
<tbody>
{procurement_plans.requisitions_procurement_plan && Array.isArray(procurement_plans.requisitions_procurement_plan) &&
procurement_plans.requisitions_procurement_plan.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/requisitions/requisitions-view/?id=${item.id}`)}>
<td data-label="requisition_number">
{ item.requisition_number }
</td>
<td data-label="title">
{ item.title }
</td>
<td data-label="procurement_method">
{ item.procurement_method }
</td>
<td data-label="estimated_amount">
{ item.estimated_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="needed_by_date">
{ dataFormatter.dateTimeFormatter(item.needed_by_date) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="rejection_reason">
{ item.rejection_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!procurement_plans?.requisitions_procurement_plan?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/procurement_plans/procurement_plans-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/procurement_plans/procurement_plansSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ProcurementPlansView = () => (
<EntityRecordViewPage
singularLabel="Procurement Plan"
pluralLabel="Procurement Plans"
stateKey="procurement_plans"
recordKey="procurement_plans"
fetchRecord={fetch}
listHref="/procurement_plans/procurement_plans-list"
editHref={(id) => `/procurement_plans/procurement_plans-edit/?id=${id ?? ''}`}
/>
);
ProcurementPlansView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_PROCUREMENT_PLANS'}>{page}</LayoutAuthenticated>;
};
Procurement_plansView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PROCUREMENT_PLANS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Procurement_plansView;
export default ProcurementPlansView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,28 +344,14 @@ const EditProgramsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Program"
pluralLabel="Programs"
listHref="/programs/programs-list"
viewHref={`/programs/programs-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1006,6 +993,7 @@ const EditProgramsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/programs/programs-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditProject_milestonesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Project' labelFor='project'>
<EnhancedEntityEditShell
entityLabel="Project Milestone"
pluralLabel="Project Milestones"
listHref="/project_milestones/project_milestones-list"
viewHref={`/project_milestones/project_milestones-view/?id=${id}`}
record={initialValues}
>
<FormField label='Project' labelFor='project'>
<Field
name='project'
id='project'
@ -916,6 +902,7 @@ const EditProject_milestonesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/project_milestones/project_milestones-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,653 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/project_milestones/project_milestonesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Project_milestonesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { project_milestones } = useAppSelector((state) => state.project_milestones)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View project_milestones')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View project_milestones')} main>
<BaseButton
color='info'
label='Edit'
href={`/project_milestones/project_milestones-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Project</p>
<p>{project_milestones?.project?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>MilestoneName</p>
<p>{project_milestones?.name}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={project_milestones?.description} />
</FormField>
<FormField label='PlannedStartDate'>
{project_milestones.planned_start_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={project_milestones.planned_start_date ?
new Date(
dayjs(project_milestones.planned_start_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No PlannedStartDate</p>}
</FormField>
<FormField label='PlannedEndDate'>
{project_milestones.planned_end_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={project_milestones.planned_end_date ?
new Date(
dayjs(project_milestones.planned_end_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No PlannedEndDate</p>}
</FormField>
<FormField label='ActualEndDate'>
{project_milestones.actual_end_date ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={project_milestones.actual_end_date ?
new Date(
dayjs(project_milestones.actual_end_date).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ActualEndDate</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{project_milestones?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>WeightPercent</p>
<p>{project_milestones?.weight_percent || 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{project_milestones?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/project_milestones/project_milestones-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/project_milestones/project_milestonesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const ProjectMilestonesView = () => (
<EntityRecordViewPage
singularLabel="Project Milestone"
pluralLabel="Project Milestones"
stateKey="project_milestones"
recordKey="project_milestones"
fetchRecord={fetch}
listHref="/project_milestones/project_milestones-list"
editHref={(id) => `/project_milestones/project_milestones-edit/?id=${id ?? ''}`}
/>
);
ProjectMilestonesView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_PROJECT_MILESTONES'}>{page}</LayoutAuthenticated>;
};
Project_milestonesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PROJECT_MILESTONES'}
>
{page}
</LayoutAuthenticated>
)
}
export default Project_milestonesView;
export default ProjectMilestonesView;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -203,28 +204,14 @@ const EditProvincesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Province"
pluralLabel="Provinces"
listHref="/provinces/provinces-list"
viewHref={`/provinces/provinces-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -466,6 +453,7 @@ const EditProvincesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/provinces/provinces-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,894 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/provinces/provincesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/provinces/provincesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
import {hasPermission} from "../../helpers/userPermissions";
const ProvincesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { provinces } = useAppSelector((state) => state.provinces)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View provinces')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View provinces')} main>
<BaseButton
color='info'
label='Edit'
href={`/provinces/provinces-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{provinces?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ProvinceName</p>
<p>{provinces?.name}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ProvinceCode</p>
<p>{provinces?.code}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{provinces?.status ?? 'No data'}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Allocations Province</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>AllocationAmount</th>
<th>Currency</th>
<th>AllocatedAt</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{provinces.allocations_province && Array.isArray(provinces.allocations_province) &&
provinces.allocations_province.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/allocations/allocations-view/?id=${item.id}`)}>
<td data-label="amount">
{ item.amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="allocated_at">
{ dataFormatter.dateTimeFormatter(item.allocated_at) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="notes">
{ item.notes }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!provinces?.allocations_province?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Requisitions Province</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>RequisitionNumber</th>
<th>Title</th>
<th>ProcurementMethod</th>
<th>EstimatedAmount</th>
<th>Currency</th>
<th>NeededByDate</th>
<th>Status</th>
<th>SubmittedAt</th>
<th>RejectionReason</th>
</tr>
</thead>
<tbody>
{provinces.requisitions_province && Array.isArray(provinces.requisitions_province) &&
provinces.requisitions_province.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/requisitions/requisitions-view/?id=${item.id}`)}>
<td data-label="requisition_number">
{ item.requisition_number }
</td>
<td data-label="title">
{ item.title }
</td>
<td data-label="procurement_method">
{ item.procurement_method }
</td>
<td data-label="estimated_amount">
{ item.estimated_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="needed_by_date">
{ dataFormatter.dateTimeFormatter(item.needed_by_date) }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="rejection_reason">
{ item.rejection_reason }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!provinces?.requisitions_province?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Projects Province</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>ProjectName</th>
<th>ProjectCode</th>
<th>ImplementingEntity</th>
<th>StartDate</th>
<th>EndDate</th>
<th>PlannedBudget</th>
<th>Currency</th>
<th>CompletionPercent</th>
<th>Status</th>
<th>RiskLevel</th>
<th>ReportingCycle</th>
<th>LastReportedAt</th>
</tr>
</thead>
<tbody>
{provinces.projects_province && Array.isArray(provinces.projects_province) &&
provinces.projects_province.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/projects/projects-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="project_code">
{ item.project_code }
</td>
<td data-label="implementing_entity">
{ item.implementing_entity }
</td>
<td data-label="start_date">
{ dataFormatter.dateTimeFormatter(item.start_date) }
</td>
<td data-label="end_date">
{ dataFormatter.dateTimeFormatter(item.end_date) }
</td>
<td data-label="planned_budget">
{ item.planned_budget }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="completion_percent">
{ item.completion_percent }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="risk_level">
{ item.risk_level }
</td>
<td data-label="reporting_cycle">
{ item.reporting_cycle }
</td>
<td data-label="last_reported_at">
{ dataFormatter.dateTimeFormatter(item.last_reported_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!provinces?.projects_province?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Beneficiaries Province</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>BeneficiaryName</th>
<th>BeneficiaryType</th>
<th>RegistrationNumber</th>
<th>ContactEmail</th>
<th>ContactPhone</th>
<th>ApprovedAmount</th>
<th>Currency</th>
<th>Status</th>
<th>ApprovedAt</th>
</tr>
</thead>
<tbody>
{provinces.beneficiaries_province && Array.isArray(provinces.beneficiaries_province) &&
provinces.beneficiaries_province.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/beneficiaries/beneficiaries-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
<td data-label="beneficiary_type">
{ item.beneficiary_type }
</td>
<td data-label="registration_number">
{ item.registration_number }
</td>
<td data-label="contact_email">
{ item.contact_email }
</td>
<td data-label="contact_phone">
{ item.contact_phone }
</td>
<td data-label="approved_amount">
{ item.approved_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="approved_at">
{ dataFormatter.dateTimeFormatter(item.approved_at) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!provinces?.beneficiaries_province?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/provinces/provinces-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
const ProvincesView = () => (
<EntityRecordViewPage
singularLabel="Province"
pluralLabel="Provinces"
stateKey="provinces"
recordKey="provinces"
fetchRecord={fetch}
listHref="/provinces/provinces-list"
editHref={(id) => `/provinces/provinces-edit/?id=${id ?? ''}`}
/>
);
ProvincesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_PROVINCES'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_PROVINCES'}>{page}</LayoutAuthenticated>;
};
export default ProvincesView;
export default ProvincesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -539,28 +540,14 @@ const EditRequisitionsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Requisition"
pluralLabel="Requisitions"
listHref="/requisitions/requisitions-list"
viewHref={`/requisitions/requisitions-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1800,6 +1787,7 @@ const EditRequisitionsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/requisitions/requisitions-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -427,29 +428,14 @@ const EditRisksPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Project' labelFor='project'>
<EnhancedEntityEditShell
entityLabel="Risk"
pluralLabel="Risks"
listHref="/risks/risks-list"
viewHref={`/risks/risks-view/?id=${id}`}
record={initialValues}
>
<FormField label='Project' labelFor='project'>
<Field
name='project'
id='project'
@ -1227,6 +1213,7 @@ const EditRisksPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/risks/risks-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,846 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/risks/risksSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const RisksView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { risks } = useAppSelector((state) => state.risks)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View risks')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View risks')} main>
<BaseButton
color='info'
label='Edit'
href={`/risks/risks-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Project</p>
<p>{risks?.project?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>RiskTitle</p>
<p>{risks?.title}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={risks?.description} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Category</p>
<p>{risks?.category ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Likelihood</p>
<p>{risks?.likelihood ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Impact</p>
<p>{risks?.impact ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{risks?.status ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>MitigationPlan</p>
{risks.mitigation_plan
? <p dangerouslySetInnerHTML={{__html: risks.mitigation_plan}}/>
: <p>No data</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Owner</p>
<p>{risks?.owner_user?.firstName ?? 'No data'}</p>
</div>
<FormField label='IdentifiedAt'>
{risks.identified_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={risks.identified_at ?
new Date(
dayjs(risks.identified_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No IdentifiedAt</p>}
</FormField>
<FormField label='ReviewDueAt'>
{risks.review_due_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={risks.review_due_at ?
new Date(
dayjs(risks.review_due_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ReviewDueAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{risks?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/risks/risks-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/risks/risksSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const RisksView = () => (
<EntityRecordViewPage
singularLabel="Risk"
pluralLabel="Risks"
stateKey="risks"
recordKey="risks"
fetchRecord={fetch}
listHref="/risks/risks-list"
editHref={(id) => `/risks/risks-edit/?id=${id ?? ''}`}
/>
);
RisksView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_RISKS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_RISKS'}>{page}</LayoutAuthenticated>;
};
export default RisksView;
export default RisksView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -175,29 +176,14 @@ const EditRole_permissionsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Role' labelFor='role'>
<EnhancedEntityEditShell
entityLabel="Role Permission"
pluralLabel="Role Permissions"
listHref="/role_permissions/role_permissions-list"
viewHref={`/role_permissions/role_permissions-view/?id=${id}`}
record={initialValues}
>
<FormField label='Role' labelFor='role'>
<Field
name='role'
id='role'
@ -610,6 +596,7 @@ const EditRole_permissionsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/role_permissions/role_permissions-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,540 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/role_permissions/role_permissionsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/role_permissions/role_permissionsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
import {hasPermission} from "../../helpers/userPermissions";
const RolePermissionsView = () => (
<EntityRecordViewPage
singularLabel="Role Permission"
pluralLabel="Role Permissions"
stateKey="role_permissions"
recordKey="role_permissions"
fetchRecord={fetch}
listHref="/role_permissions/role_permissions-list"
editHref={(id) => `/role_permissions/role_permissions-edit/?id=${id ?? ''}`}
/>
);
const Role_permissionsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { role_permissions } = useAppSelector((state) => state.role_permissions)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View role_permissions')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View role_permissions')} main>
<BaseButton
color='info'
label='Edit'
href={`/role_permissions/role_permissions-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Role</p>
<p>{role_permissions?.role?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Permission</p>
<p>{role_permissions?.permission?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{role_permissions?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/role_permissions/role_permissions-list')}
/>
</CardBox>
</SectionMain>
</>
);
RolePermissionsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_ROLE_PERMISSIONS'}>{page}</LayoutAuthenticated>;
};
Role_permissionsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_ROLE_PERMISSIONS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Role_permissionsView;
export default RolePermissionsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -175,10 +176,14 @@ const EditRolesPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField
<EnhancedEntityEditShell
entityLabel="Role"
pluralLabel="Roles"
listHref="/roles/roles-list"
viewHref={`/roles/roles-view/?id=${id}`}
record={initialValues}
>
<FormField
label="Name"
>
<Field
@ -396,6 +401,7 @@ const EditRolesPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/roles/roles-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,588 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/roles/rolesSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/roles/rolesSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
import {hasPermission} from "../../helpers/userPermissions";
const RolesView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { roles } = useAppSelector((state) => state.roles)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View roles')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View roles')} main>
<BaseButton
color='info'
label='Edit'
href={`/roles/roles-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Name</p>
<p>{roles?.name}</p>
</div>
<>
<p className={'block font-bold mb-2'}>Permissions</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{roles.permissions && Array.isArray(roles.permissions) &&
roles.permissions.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/permissions/permissions-view/?id=${item.id}`)}>
<td data-label="name">
{ item.name }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!roles?.permissions?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<FormField label='Global Access'>
<SwitchField
field={{name: 'globalAccess', value: roles?.globalAccess}}
form={{setFieldValue: () => null}}
disabled
/>
</FormField>
<>
<p className={'block font-bold mb-2'}>Users App Role</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
<th>E-Mail</th>
<th>Disabled</th>
</tr>
</thead>
<tbody>
{roles.users_app_role && Array.isArray(roles.users_app_role) &&
roles.users_app_role.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/users/users-view/?id=${item.id}`)}>
<td data-label="firstName">
{ item.firstName }
</td>
<td data-label="lastName">
{ item.lastName }
</td>
<td data-label="phoneNumber">
{ item.phoneNumber }
</td>
<td data-label="email">
{ item.email }
</td>
<td data-label="disabled">
{ dataFormatter.booleanFormatter(item.disabled) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!roles?.users_app_role?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Role_permissions Role</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
</tr>
</thead>
<tbody>
{roles.role_permissions_role && Array.isArray(roles.role_permissions_role) &&
roles.role_permissions_role.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/role_permissions/role_permissions-view/?id=${item.id}`)}>
</tr>
))}
</tbody>
</table>
</div>
{!roles?.role_permissions_role?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Approval_steps ApproverRole</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>StepOrder</th>
<th>StepName</th>
<th>MinimumAmount</th>
<th>MaximumAmount</th>
<th>RequiresComment</th>
</tr>
</thead>
<tbody>
{roles.approval_steps_approver_role && Array.isArray(roles.approval_steps_approver_role) &&
roles.approval_steps_approver_role.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/approval_steps/approval_steps-view/?id=${item.id}`)}>
<td data-label="step_order">
{ item.step_order }
</td>
<td data-label="name">
{ item.name }
</td>
<td data-label="min_amount">
{ item.min_amount }
</td>
<td data-label="max_amount">
{ item.max_amount }
</td>
<td data-label="requires_comment">
{ dataFormatter.booleanFormatter(item.requires_comment) }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!roles?.approval_steps_approver_role?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/roles/roles-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
const RolesView = () => (
<EntityRecordViewPage
singularLabel="Role"
pluralLabel="Roles"
stateKey="roles"
recordKey="roles"
fetchRecord={fetch}
listHref="/roles/roles-list"
editHref={(id) => `/roles/roles-edit/?id=${id ?? ''}`}
/>
);
RolesView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_ROLES'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_ROLES'}>{page}</LayoutAuthenticated>;
};
export default RolesView;
export default RolesView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -399,28 +400,14 @@ const EditTendersPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Tender"
pluralLabel="Tenders"
listHref="/tenders/tenders-list"
viewHref={`/tenders/tenders-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1049,6 +1036,7 @@ const EditTendersPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/tenders/tenders-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,904 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/tenders/tendersSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const TendersView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { tenders } = useAppSelector((state) => state.tenders)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View tenders')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View tenders')} main>
<BaseButton
color='info'
label='Edit'
href={`/tenders/tenders-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Organization</p>
<p>{tenders?.organization?.name ?? 'No data'}</p>
</div>
}
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Requisition</p>
<p>{tenders?.requisition?.requisition_number ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TenderNumber</p>
<p>{tenders?.tender_number}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Title</p>
<p>{tenders?.title}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>TenderType</p>
<p>{tenders?.tender_type ?? 'No data'}</p>
</div>
<FormField label='PublishedAt'>
{tenders.published_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={tenders.published_at ?
new Date(
dayjs(tenders.published_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No PublishedAt</p>}
</FormField>
<FormField label='ClosingAt'>
{tenders.closing_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={tenders.closing_at ?
new Date(
dayjs(tenders.closing_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ClosingAt</p>}
</FormField>
<FormField label='OpeningAt'>
{tenders.opening_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={tenders.opening_at ?
new Date(
dayjs(tenders.opening_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No OpeningAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{tenders?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={tenders?.eligibility_criteria} />
</FormField>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={tenders?.submission_instructions} />
</FormField>
<>
<p className={'block font-bold mb-2'}>Bids Tender</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>BidReference</th>
<th>SubmittedAt</th>
<th>BidAmount</th>
<th>Currency</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{tenders.bids_tender && Array.isArray(tenders.bids_tender) &&
tenders.bids_tender.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/bids/bids-view/?id=${item.id}`)}>
<td data-label="bid_reference">
{ item.bid_reference }
</td>
<td data-label="submitted_at">
{ dataFormatter.dateTimeFormatter(item.submitted_at) }
</td>
<td data-label="bid_amount">
{ item.bid_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="status">
{ item.status }
</td>
<td data-label="notes">
{ item.notes }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!tenders?.bids_tender?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<>
<p className={'block font-bold mb-2'}>Awards Tender</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
>
<div className='overflow-x-auto'>
<table>
<thead>
<tr>
<th>AwardNumber</th>
<th>AwardAmount</th>
<th>Currency</th>
<th>DecisionDate</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{tenders.awards_tender && Array.isArray(tenders.awards_tender) &&
tenders.awards_tender.map((item: any) => (
<tr key={item.id} onClick={() => router.push(`/awards/awards-view/?id=${item.id}`)}>
<td data-label="award_number">
{ item.award_number }
</td>
<td data-label="award_amount">
{ item.award_amount }
</td>
<td data-label="currency">
{ item.currency }
</td>
<td data-label="decision_date">
{ dataFormatter.dateTimeFormatter(item.decision_date) }
</td>
<td data-label="status">
{ item.status }
</td>
</tr>
))}
</tbody>
</table>
</div>
{!tenders?.awards_tender?.length && <div className={'text-center py-4'}>No data</div>}
</CardBox>
</>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/tenders/tenders-list')}
/>
</CardBox>
</SectionMain>
</>
);
};
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/tenders/tendersSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const TendersView = () => (
<EntityRecordViewPage
singularLabel="Tender"
pluralLabel="Tenders"
stateKey="tenders"
recordKey="tenders"
fetchRecord={fetch}
listHref="/tenders/tenders-list"
editHref={(id) => `/tenders/tenders-edit/?id=${id ?? ''}`}
/>
);
TendersView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_TENDERS'}
>
{page}
</LayoutAuthenticated>
)
}
return <LayoutAuthenticated permission={'READ_TENDERS'}>{page}</LayoutAuthenticated>;
};
export default TendersView;
export default TendersView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -345,10 +346,14 @@ const EditUsersPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField
<EnhancedEntityEditShell
entityLabel="User"
pluralLabel="Users"
listHref="/users/users-list"
viewHref={`/users/users-view/?id=${id}`}
record={initialValues}
>
<FormField
label="First Name"
>
<Field
@ -1014,6 +1019,7 @@ const EditUsersPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/users/users-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -343,29 +344,14 @@ const EditVendor_compliance_documentsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Vendor' labelFor='vendor'>
<EnhancedEntityEditShell
entityLabel="Vendor Compliance Document"
pluralLabel="Vendor Compliance Documents"
listHref="/vendor_compliance_documents/vendor_compliance_documents-list"
viewHref={`/vendor_compliance_documents/vendor_compliance_documents-view/?id=${id}`}
record={initialValues}
>
<FormField label='Vendor' labelFor='vendor'>
<Field
name='vendor'
id='vendor'
@ -927,6 +913,7 @@ const EditVendor_compliance_documentsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/vendor_compliance_documents/vendor_compliance_documents-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

View File

@ -1,654 +1,22 @@
import React, { ReactElement, useEffect } from 'react';
import Head from 'next/head'
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import dayjs from "dayjs";
import {useAppDispatch, useAppSelector} from "../../stores/hooks";
import {useRouter} from "next/router";
import { fetch } from '../../stores/vendor_compliance_documents/vendor_compliance_documentsSlice'
import {saveFile} from "../../helpers/fileSaver";
import dataFormatter from '../../helpers/dataFormatter';
import ImageField from "../../components/ImageField";
import LayoutAuthenticated from "../../layouts/Authenticated";
import {getPageTitle} from "../../config";
import SectionTitleLineWithButton from "../../components/SectionTitleLineWithButton";
import SectionMain from "../../components/SectionMain";
import CardBox from "../../components/CardBox";
import BaseButton from "../../components/BaseButton";
import BaseDivider from "../../components/BaseDivider";
import {mdiChartTimelineVariant} from "@mdi/js";
import {SwitchField} from "../../components/SwitchField";
import FormField from "../../components/FormField";
import {hasPermission} from "../../helpers/userPermissions";
const Vendor_compliance_documentsView = () => {
const router = useRouter()
const dispatch = useAppDispatch()
const { vendor_compliance_documents } = useAppSelector((state) => state.vendor_compliance_documents)
const { currentUser } = useAppSelector((state) => state.auth);
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
return (
<>
<Head>
<title>{getPageTitle('View vendor_compliance_documents')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View vendor_compliance_documents')} main>
<BaseButton
color='info'
label='Edit'
href={`/vendor_compliance_documents/vendor_compliance_documents-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>
<CardBox>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Vendor</p>
<p>{vendor_compliance_documents?.vendor?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>DocumentType</p>
<p>{vendor_compliance_documents?.document_type ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>ReferenceNumber</p>
<p>{vendor_compliance_documents?.reference_number}</p>
</div>
<FormField label='IssuedAt'>
{vendor_compliance_documents.issued_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={vendor_compliance_documents.issued_at ?
new Date(
dayjs(vendor_compliance_documents.issued_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No IssuedAt</p>}
</FormField>
<FormField label='ExpiresAt'>
{vendor_compliance_documents.expires_at ? <DatePicker
dateFormat="yyyy-MM-dd hh:mm"
showTimeSelect
selected={vendor_compliance_documents.expires_at ?
new Date(
dayjs(vendor_compliance_documents.expires_at).format('YYYY-MM-DD hh:mm'),
) : null
}
disabled
/> : <p>No ExpiresAt</p>}
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Status</p>
<p>{vendor_compliance_documents?.status ?? 'No data'}</p>
</div>
<FormField label='Multi Text' hasTextareaHeight>
<textarea className={'w-full'} disabled value={vendor_compliance_documents?.review_comment} />
</FormField>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>File</p>
{vendor_compliance_documents?.file?.length
? dataFormatter.filesFormatter(vendor_compliance_documents.file).map(link => (
<button
key={link.publicUrl}
onClick={(e) => saveFile(e, link.publicUrl, link.name)}
>
{link.name}
</button>
)) : <p>No File</p>
}
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>organizations</p>
<p>{vendor_compliance_documents?.organizations?.name ?? 'No data'}</p>
</div>
<BaseDivider />
<BaseButton
color='info'
label='Back'
onClick={() => router.push('/vendor_compliance_documents/vendor_compliance_documents-list')}
/>
</CardBox>
</SectionMain>
</>
);
import React, { ReactElement } from 'react';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { fetch } from '../../stores/vendor_compliance_documents/vendor_compliance_documentsSlice';
import EntityRecordViewPage from '../../components/EntityPage/EntityRecordViewPage';
const VendorComplianceDocumentsView = () => (
<EntityRecordViewPage
singularLabel="Vendor Compliance Document"
pluralLabel="Vendor Compliance Documents"
stateKey="vendor_compliance_documents"
recordKey="vendor_compliance_documents"
fetchRecord={fetch}
listHref="/vendor_compliance_documents/vendor_compliance_documents-list"
editHref={(id) => `/vendor_compliance_documents/vendor_compliance_documents-edit/?id=${id ?? ''}`}
/>
);
VendorComplianceDocumentsView.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated permission={'READ_VENDOR_COMPLIANCE_DOCUMENTS'}>{page}</LayoutAuthenticated>;
};
Vendor_compliance_documentsView.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated
permission={'READ_VENDOR_COMPLIANCE_DOCUMENTS'}
>
{page}
</LayoutAuthenticated>
)
}
export default Vendor_compliance_documentsView;
export default VendorComplianceDocumentsView;

View File

@ -10,6 +10,7 @@ import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import EnhancedEntityEditShell from '../../components/EntityPage/EnhancedEntityEditShell'
import { Field, Form, Formik } from 'formik'
import FormField from '../../components/FormField'
@ -623,28 +624,14 @@ const EditVendorsPage = () => {
onSubmit={(values) => handleSubmit(values)}
>
<Form>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<EnhancedEntityEditShell
entityLabel="Vendor"
pluralLabel="Vendors"
listHref="/vendors/vendors-list"
viewHref={`/vendors/vendors-view/?id=${id}`}
record={initialValues}
>
{hasPermission(currentUser, 'READ_ORGANIZATIONS') &&
<FormField label='Organization' labelFor='organization'>
<Field
name='organization'
@ -1465,6 +1452,7 @@ const EditVendorsPage = () => {
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/vendors/vendors-list')}/>
</BaseButtons>
</EnhancedEntityEditShell>
</Form>
</Formik>
</CardBox>

Some files were not shown because too many files have changed in this diff Show More