Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ db/migrations/plugins/*
!db/migrations/plugins/.keep


backend/models/core/Entity_old.js
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,3 @@ Screnshots: https://cms.demo.klaudsol.app
<img width="1678" alt="image" src="https://github.com/klaudsol/klaudsol-cms/assets/1546228/9836b2b3-d006-4124-9fe8-5521eb6a2433">






25 changes: 20 additions & 5 deletions backend/models/core/Entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,21 @@ class Entity {
? { booleanValue: entry[attributeName] }
: { isNull: true },
},
{
name: "value_datetime",
value:
attributeType == "datetime"
? { stringValue: entry[attributeName] }
: { isNull: true },
},
],
];
}, []);

//Insert Values by batch
const insertValuesBatchSQL = `INSERT INTO \`values\`(entity_id, attribute_id,
value_string, value_long_string, value_double, value_boolean
) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_double, :value_boolean)
value_string, value_long_string, value_datetime, value_double, value_boolean
) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_datetime, :value_double, :value_boolean)
`;

await db.batchExecuteStatement(insertValuesBatchSQL, valueBatchParams);
Expand Down Expand Up @@ -449,6 +456,13 @@ class Entity {
? { booleanValue: entries[attributeName] }
: { isNull: true },
},
{
name: "value_datetime",
value:
attributeType == "datetime"
? { stringValue: entries[attributeName] }
: { isNull: true },
},
],
];
}, []);
Expand Down Expand Up @@ -484,8 +498,8 @@ class Entity {

if (nonExistingVal.length) {
const insertValuesBatchSQL = `INSERT INTO \`values\`(entity_id, attribute_id,
value_string, value_long_string, value_double, value_boolean
) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_double, :value_boolean)
value_string, value_long_string, value_datetime, value_double, value_boolean
) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_datetime, :value_double, :value_boolean)
`;

await db.batchExecuteStatement(insertValuesBatchSQL, nonExistingVal);
Expand All @@ -496,6 +510,7 @@ class Entity {
const updateValuesBatchSQL = `UPDATE \`values\` SET
value_string = :value_string,
value_long_string = :value_long_string,
value_datetime = :value_datetime,
value_double = :value_double,
value_boolean = :value_boolean
WHERE entity_id = :entity_id AND attribute_id = :attribute_id
Expand All @@ -508,4 +523,4 @@ class Entity {
}
}

export default Entity;
export default Entity;
4 changes: 4 additions & 0 deletions components/EntityAttributeValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const formatImage = (key) => {
case 'float':
//TODO: Find a more accurate representation of float
return Number(item.value_double);
//added for datetime
case 'datetime':
return item.value_datetime;

case 'custom':
const CustomAttributeType = plugin(item.attributes_custom_name);
const customAttributeType = new CustomAttributeType({
Expand Down
1 change: 1 addition & 0 deletions components/attribute_types/AttributeType.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class AttributeType {
static TEXT_CMS_TYPE = 'text';
static TEXTAREA_CMS_TYPE = 'textarea';
static RICH_TEXT_CMS_TYPE = 'rich-text';
static DATETIME_CMS_TYPE = 'datetime';
static CUSTOM = 'custom';


Expand Down
3 changes: 3 additions & 0 deletions components/attribute_types/AttributeTypeFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import TextareaAttributeType from "@/components/attribute_types/TextareaAttribut
import LegacyAttributeType from '@/components/attribute_types/LegacyAttributeType';
import { plugin } from '@/components/plugin/plugin';
import RichTextAttributeType from '@/components/attribute_types/RichTextAttributeType';
import DateTimeAttributeType from '@/components/attribute_types/DateTimeAttributeType';

export default class AttributeTypeFactory {
static create({data, metadata}) {
Expand All @@ -14,6 +15,8 @@ export default class AttributeTypeFactory {
return new TextareaAttributeType({data, metadata});
case AttributeType.RICH_TEXT_CMS_TYPE:
return new RichTextAttributeType({data, metadata});
case AttributeType.DATETIME_CMS_TYPE:
return new DateTimeAttributeType({data, metadata});
case AttributeType.CUSTOM:
const CustomAttributeType = plugin(metadata.custom_name);
return new CustomAttributeType({data, metadata});
Expand Down
53 changes: 53 additions & 0 deletions components/attribute_types/DateTimeAttributeType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import AttributeType from '@/components/attribute_types/AttributeType';
import { useFormikContext, useField } from "formik";
import { useState, useEffect } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import moment from 'moment';

const DateTimeAttributeReadOnlyComponent = ({ text }) => {
const parsedDate = new Date(text);
const formattedDate = moment(parsedDate).format('MMM. D, YYYY - hh:mm A');

return <>{formattedDate}</>;
};


const DateTimeAttributeEditableComponent = ({ name }) => {
const { setFieldValue } = useFormikContext();
const [{ value }] = useField(name);
const [selectedDate, setSelectedDate] = useState(value ? new Date(value) : new Date()); // Set initial selected date to today

useEffect(() => {
if (selectedDate) {
const formattedDate = moment(selectedDate).format('YYYY-MM-DD HH:mm');
setFieldValue(name, formattedDate);
} else {
setFieldValue(name, null);
}
}, [selectedDate, name, setFieldValue]);

const handleDateChange = (date) => {
setSelectedDate(date);
};

return (
<DatePicker
selected={selectedDate}
onChange={handleDateChange}
showTimeSelect
timeFormat="hh:mm aa"
dateFormat="MMM. d, yyyy - hh:mm aa"
/>
);
};

export default class DateTimeAttributeType extends AttributeType {
readOnlyComponent() {
return DateTimeAttributeReadOnlyComponent;
}

editableComponent() {
return DateTimeAttributeEditableComponent;
}
}
4 changes: 3 additions & 1 deletion components/cmsTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export const CMS_TYPES = {
PASSWORD: "password",
CHECKBOX: "checkbox",
CUSTOM: "custom",
RICH_TEXT: "rich-text"
RICH_TEXT: "rich-text",
DATETIME: "datetime" //added for datetime

};

// resources types
Expand Down
2 changes: 2 additions & 0 deletions components/renderers/admin/AdminRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import VideoRenderer from "./VideoRenderer";
import BooleanRenderer from "./BooleanRenderer";
import { plugin } from "@/components/plugin/plugin";
import RichTextAttributeType from "@/components/attribute_types/RichTextAttributeType";
import DateTimeAttributeType from "@/components/attribute_types/DateTimeAttributeType";
import AttributeTypeFactory from "@/components/attribute_types/AttributeTypeFactory";

const AdminRenderer = ({ type, ...params }) => {
Expand All @@ -35,6 +36,7 @@ const AdminRenderer = ({ type, ...params }) => {
case CMS_TYPES.BOOLEAN:
return <BooleanRenderer type={type} {...params} title="Yes" />;
case CMS_TYPES.RICH_TEXT:
case CMS_TYPES.DATETIME:
case CMS_TYPES.CUSTOM:
const attributeType = AttributeTypeFactory.create({metadata: {type, custom_name: params.customName, id: params.id}});
const Component = attributeType.editableComponent();
Expand Down
1 change: 1 addition & 0 deletions constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const inputValues = [
{ value: "gallery", option: "Gallery" },
{ value: "float", option: "Number" },
{ value: "video", option: "Video" },
{ value: "datetime", option: "DateTime" },
{ value: "boolean", option: "Boolean" },
{ value: "custom", option: "Custom" }
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
"DELETE FROM group_capabilities WHERE group_id IN (1, 2) ",
"AND capabilities_id = (SELECT id FROM capabilities WHERE name = 'read_pending_users' AND is_system_supplied = true);"
]
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"react-component-export-image": "^1.0.6",
"react-confirm-alert": "2.0.2",
"react-csv-downloader": "^2.8.0",
"react-datepicker": "^4.8.0",
"react-datepicker": "^4.14.1",
"react-dom": "^18.2.0",
"react-hook-form": "^7.33.0",
"react-icons": "^4.3.1",
Expand Down
14 changes: 14 additions & 0 deletions styles/klaudsolcms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1398,3 +1398,17 @@ $onFocus: #323C4E;
font-weight: 590;
}
}

//modify the datepicker popup
.react-datepicker__input-container input {
padding: 8px;
border-radius: 5px;
border: 1px solid #ccc !important;
}
// change the selected date color
.react-datepicker__day--selected, .react-datepicker__time-list-item--selected {
background-color: #467286 !important;
}
.react-datepicker__time-container {
overflow: hidden;
}
Loading