diff --git a/demo-project.css b/demo-project.css
deleted file mode 100644
index bedef6c..0000000
--- a/demo-project.css
+++ /dev/null
@@ -1,80 +0,0 @@
-.ryz-project {
- border-spacing: 0px;
- border-collapse: separate;
- cursor: default;
- padding: 0px 0px 30px 0px;
- width: 100%;
-}
-
-.ryz-project .b {
- font-weight: bold;
-}
-.ryz-project .c {
- text-align: center;
-}
-.ryz-project .i {
- display: inline-block;
- width: 20px;
-}
-
-.ryz-project thead tr {
- font-weight: bold;
- font-size: 0.8em;
- user-select: none;
- height: 40px;
- text-align: center;
- vertical-align: bottom;
-}
-.ryz-project thead tr th {
- background-color: #E1E1E1;
- border-color: #B8B8B8;
- border-style: solid;
- border-width: 0px 0px 1px 1px;
- color: #3E7138;
- margin: 0px;
- padding: 6px 10px 5px 10px;
- min-width: 20px;
-}
-.ryz-project thead tr th:first-child {
- background-color: inherit;
- border-left-width: 0px;
-}
-.ryz-project thead tr th:last-child {
- border-right-width: 1px;
-}
-
-.ryz-project tbody tr td {
- border-color: #B8B8B8;
- border-style: solid;
- border-width: 0px 0px 1px 0px;
- margin: 0px;
- overflow: hidden;
- padding: 5px 5px 5px 5px;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-.ryz-project tbody tr td:first-child {
- border-right-width: 1px;
- color: #7E7E7E;
- font-size: 0.8em;
- text-align: center;
- user-select: none;
-}
-.ryz-project tbody tr td:last-child {
- border-right-width: 1px;
-}
-
-.ryz-project tbody tr:hover td:first-child {
- background-color: #D1F2C7;
- color: #3E7138;
- font-weight: bold;
-}
-
-
-
-
-.border {
- border-color: #B8B8B8;
- border-style: solid;
- border-width: 1px;
-}
\ No newline at end of file
diff --git a/demo-project.html b/demo-project.html
deleted file mode 100644
index c9eff55..0000000
--- a/demo-project.html
+++ /dev/null
@@ -1,178 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/devnotes.txt b/devnotes.txt
deleted file mode 100644
index ff0f2a7..0000000
--- a/devnotes.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-npm install --save-dev webpack webpack-cli
-npm run build
\ No newline at end of file
diff --git a/package.json b/package.json
index daf304f..4e821d1 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,16 @@
{
"name": "LiteRyzJS",
- "version": "0.1.0.154",
+ "version": "0.1.0.455",
"devDependencies": {
+ "css-loader": "^7.1.2",
+ "sass": "^1.77.8",
+ "sass-loader": "^16.0.0",
+ "style-loader": "^4.0.0",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4"
},
"scripts": {
- "build": "webpack"
+ "build": "webpack",
+ "watch": "webpack --watch"
}
}
\ No newline at end of file
diff --git a/src/extensions/array.js b/src/extensions/array.js
index 95222c6..38eaab4 100644
--- a/src/extensions/array.js
+++ b/src/extensions/array.js
@@ -1,4 +1,13 @@
+/**
+ * Check is array empty.
+ * @param {Array} value Array.
+ * @returns Boolean True, if array is empty or not an array type.
+ */
Array.isEmpty = function(value) {
+ if (typeof(value) == "undefined") {
+ return true;
+ }
+
const dataType = Object.getDataType(value);
if (dataType != "array") {
return true;
@@ -7,6 +16,12 @@ Array.isEmpty = function(value) {
return (value.length <= 0);
};
+/**
+ * Create a linear/one-dimension array of objects from an object's property.
+ * @param {*} sourceArray Source array.
+ * @param {*} propName Property name.
+ * @param {*} destArray Destination array.
+ */
Array.toFlatten = function (sourceArray, propName, destArray) {
for (let i=0; i {
+ this.push(e);
+ });
return this;
};
-Array.prototype.any = function (propName, value) {
- return (this.count(propName, value) > 0);
+/**
+ * Check all match property value.
+ * @param {String} propName Property name.
+ * @param {Object} value Property value.
+ * @returns Boolean True, if all objects of property name match value.
+ */
+Array.prototype.all = function (propName, value) {
+ for (let i = 0; i < this.length; i++) {
+ if (propName == null) {
+ if (this[i] != value){
+ return false;
+ }
+ } else {
+ if (typeof(this[i][propName]) != "undefined") {
+ if (this[i][propName] != value){
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
};
+/**
+ * Check any match property value.
+ * @param {String} propName Property name.
+ * @param {Object} value Property value.
+ * @returns Boolean True, if any objects of property name match value.
+ */
+Array.prototype.any = function (propName, value) {
+ for (let i = 0; i < this.length; i++) {
+ if (propName == null) {
+ if (this[i] == value){
+ return true;
+ }
+ } else {
+ if (typeof(this[i][propName]) != "undefined") {
+ if (this[i][propName] == value){
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+};
+
+/**
+ * Create deep copy of array.
+ * @returns Array
+ */
Array.prototype.copy = function () {
return JSON.parse(JSON.stringify(this));
};
+/**
+ * Count of objects in array with the property value.
+ * @param {*} propName Property name.
+ * @param {*} value Property value.
+ * @returns Integer Number of matches.
+ */
Array.prototype.count = function (propName, value) {
let result = 0;
@@ -60,6 +133,11 @@ Array.prototype.count = function (propName, value) {
return result;
};
+/**
+ * Count of objects in array with many matches.
+ * @param {Object} filters Array of matches [{propName, value}].
+ * @returns Integer Number of matches.
+ */
Array.prototype.countMany = function (...filters) {
let result = 0;
@@ -70,6 +148,12 @@ Array.prototype.countMany = function (...filters) {
return result;
};
+/**
+ * Create an empty array of a given length with a given default value.
+ * @param {int} length Length of array.
+ * @param {object} value Default value.
+ * @returns Array.
+ */
Array.prototype.create = function (length, value) {
let result = [];
@@ -80,6 +164,19 @@ Array.prototype.create = function (length, value) {
return result
};
+Array.prototype.distinct = function() {
+ let result = this.filter((obj, index, self) =>
+ index === self.findIndex((x) => JSON.stringify(x) === JSON.stringify(obj))
+ );
+
+ return result;
+}
+
+/**
+ * Convert this array of objects to a linear/one-dimensional array using a property.
+ * @param {*} propName Property name.
+ * @returns Array Array.
+ */
Array.prototype.flatten = function (propName) {
let result = [];
@@ -88,6 +185,29 @@ Array.prototype.flatten = function (propName) {
return result;
};
+/**
+ * Get element at index.
+ * @param {Object} index Index of element.
+ * @returns Object Element.
+ */
+Array.prototype.get = function (index) {
+ if (index < 0) {
+ return "";
+ }
+
+ if (index >= this.length) {
+ return "";
+ }
+
+ return this[index];
+};
+
+/**
+ * Find index of first occurrence of value in property.
+ * @param {string} propName Property name.
+ * @param {object} value Property value.
+ * @returns Index of element.
+ */
Array.prototype.index = function (propName, value) {
const result = this.indexes(propName, value);
if (result.length <= 0) {
@@ -97,6 +217,12 @@ Array.prototype.index = function (propName, value) {
return result[0];
};
+/**
+ * Find index of occurrences of value in property in array.
+ * @param {string} propName Property name.
+ * @param {object} value Property value.
+ * @returns Array of indexes.
+ */
Array.prototype.indexes = function (propName, value) {
let result = [];
@@ -117,6 +243,12 @@ Array.prototype.indexes = function (propName, value) {
return result;
};
+/**
+ * Insert an element into an array at index position.
+ * @param {int} index Array index.
+ * @param {object} item Array element.
+ * @returns Array.
+ */
Array.prototype.insert = function(index, item) {
if (index < 0) {
this.splice(0, 0, item);
@@ -129,6 +261,11 @@ Array.prototype.insert = function(index, item) {
return this;
};
+/**
+ * Concatenates an array if value is not null or whitespace using a separator.
+ * @param {string} separator Separator text.
+ * @returns string.
+ */
Array.prototype.joinIfNotNullOrWhitespace = function (separator) {
const a = this;
@@ -149,6 +286,12 @@ Array.prototype.joinIfNotNullOrWhitespace = function (separator) {
return result;
};
+/**
+ * Returns first element that matches.
+ * @param {string} propName Property name.
+ * @param {string} value Property value.
+ * @returns Array element.
+ */
Array.prototype.first = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
@@ -163,6 +306,11 @@ Array.prototype.first = function (propName, value) {
return null;
};
+/**
+ * Traverses an array tree following a property (by name), performing the defined function.
+ * @param {string} propName Property name.
+ * @param {function} func Function to perform at each element.
+ */
Array.prototype.forEachTree = function (propName, func) {
for (let i=0; i= this.length)) {
return this;
@@ -233,6 +401,11 @@ Array.prototype.removeAt = function(index) {
return this;
};
+/**
+ * Remove elements in an array.
+ * @param {Array} array Array of elements to be removed.
+ * @returns Array.
+ */
Array.prototype.removeRange = function (array) {
for (let i=0; i {
- if (e.FinishDate == null) {
- return;
- }
-
- result = Date.max(result, e.FinishDate);
- });
-
- return result;
- }
-
- get Duration() {
- const a = this;
-
- return Date.diffDays(a.StartDate, a.FinishDate);
- }
-
-
- get newProject() {
- return {
- Name: "",
- Description: "",
- StartDate: Date.today(),
- Tag: null,
- StartOfWeek: 1, // Monday
- WorkHours: [0, 7.5, 7.5, 7.5, 7.5, 7.5, 0] // 0 = Sunday
- };
- }
-
- get newTaskNode() {
- return {
- Order: null,
- ID: null,
- Name: "",
- Description: "",
- Tag: null,
- StartDate: null, // new Date(),
- FinishDate: null, // new Date(),
- StartDelay: 0, // Days
- Duration: 1, // Days
- PredecessorTaskID: null,
- IsCollated: false,
- CollatedTaskID: null,
- CalcWorkHours: 0,
- ActuWorkHours: null,
- Progress: 0,
- Resources: [],
- Level: 0,
- PredecessorTaskNo: null,
- Tasks: []
- };
- }
-
-
- AddTask(task) {
- const a = this;
- const newTask = Object.assign(a.NewTask, task);
- const newTaskNode = Object.assign(a.newTaskNode, newTask);
-
- if ((newTaskNode.PredecessorTaskID == null) && (newTaskNode.CollatedTaskID == null)) {
- a.Tasks.push(newTaskNode);
- } else if (newTaskNode.PredecessorTaskID != null) {
- const node = a.FindTask(newTaskNode.PredecessorTaskID);
-
- if (node != null) {
- node.Tasks.push(newTaskNode);
- } else {
- a.log("Task not found (" + newTaskNode.PredecessorTaskID + ")");
- }
- } else if (newTaskNode.CollatedTaskID != null) {
- const node = a.FindTask(newTaskNode.CollatedTaskID);
-
- if (node != null) {
- node.Tasks.push(newTaskNode);
- } else {
- a.log("Task not found (" + newTaskNode.CollatedTaskID + ")");
- }
- } else {
- a.log("Task not found (" + newTaskNode.ID + ")");
- }
- }
-
- ClearTasks() {
- const a = this;
-
- a.Tasks = [];
- }
-
- ExportTasks() {
- const a = this;
-
- let result = a.Tasks.copy().flatten("Tasks");
- for (var i=0; i {
- if (e.FinishDate > node2FinishDate) {
- node2FinishDate = e.FinishDate;
- }
- });
-
- array[index].Progress = Math.average(node2.toList("Progress"));
- array[index].FinishDate = new Date(node2FinishDate);
- array[index].Duration = Date.diffDays(array[index].StartDate, array[index].FinishDate);
- }
-
-}
-
-
-export default Project;
\ No newline at end of file
diff --git a/src/project/task-grid.js b/src/project/task-grid.js
deleted file mode 100644
index 0283fd5..0000000
--- a/src/project/task-grid.js
+++ /dev/null
@@ -1,120 +0,0 @@
-class ProjectTaskGrid {
- constructor(el) {
- const a = this;
-
- a.Container = el;
-
- a.Columns = [
- null,
- null,
- "Task Name",
- "Duration",
- "Start",
- "Finish",
- "Predecessor",
- "Resource Names",
- null
- ];
-
- a.initialiseComponents();
- }
-
- initialiseComponents() {
- const a = this;
-
- let htmlContent = "";
- htmlContent += "";
- htmlContent += a.renderTHead();
- htmlContent += "";
- htmlContent += a.renderPlaceholder();
- htmlContent += "";
- htmlContent += "
";
-
- a.Container.innerHTML = htmlContent;
- }
-
-
- Render(model) {
- const a = this;
-
- let htmlContent = "";
- htmlContent += "";
- htmlContent += a.renderTHead();
- htmlContent += "";
-
- model.forEach(e => {
- htmlContent += a.renderRow(e);
- });
-
- htmlContent += "";
- htmlContent += "
";
-
- a.Container.innerHTML = htmlContent;
- }
-
-
- renderTHead() {
- const a = this;
-
- let htmlContent = "";
- htmlContent += "";
- htmlContent += "";
-
- a.Columns.forEach(e => {
- htmlContent += "" + (e ?? "") + " | ";
- });
-
- htmlContent += "
";
- htmlContent += "";
-
- return htmlContent;
- }
-
- renderPlaceholder() {
- const a = this;
-
- let htmlContent = "";
- htmlContent += "";
- htmlContent += " | ";
- htmlContent += "Loading... | ";
- htmlContent += "
";
-
- return htmlContent;
- }
-
- renderRow(e) {
- const a = this;
-
- let htmlContent = "";
-
- if (e.IsCollated == true) {
- htmlContent += "";
- } else {
- htmlContent += "
";
- }
-
- htmlContent += "" + e.Order + " | ";
- htmlContent += " | ";
- htmlContent += "";
-
- for (let i=0; i";
- }
-
- htmlContent += e.Name;
- htmlContent += " | ";
- htmlContent += "" + e.Duration + " day" + (parseInt(e.Duration) == 1 ? "" : "s") + " | ";
- htmlContent += "" + new Date(e.StartDate).toLocaleDateString() + " | ";
- htmlContent += "" + new Date(e.FinishDate).toLocaleDateString() + " | ";
- htmlContent += "" + (e.PredecessorTaskNo ?? "") + " | ";
- htmlContent += " | ";
- htmlContent += " | ";
- htmlContent += "
";
-
- return htmlContent;
- }
-
-}
-
-
-export default ProjectTaskGrid;
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index b372ac0..9d47beb 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -30,11 +30,10 @@ class PrependVersionPlugin {
module.exports = {
entry: {
extensions: './src/extensions.js',
- graphics: './src/graphics.js',
- project: './src/project.js'
+ graphics: './src/graphics.js'
},
output: {
- filename: `[name].min.js`,
+ filename: `[name].dist.js`,
path: path.resolve(__dirname, 'dist'),
library: 'LiteRyzJS',
libraryTarget: 'umd',
@@ -46,5 +45,17 @@ module.exports = {
'process.env.VERSION': JSON.stringify(version)
}),
new PrependVersionPlugin()
- ]
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.scss$/,
+ use: [
+ 'style-loader',
+ 'css-loader',
+ 'sass-loader'
+ ]
+ }
+ ]
+ }
};
\ No newline at end of file