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 += "" + 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