Delete items from an array inside a nested object - filter

I have this object (mainArray) and I want to remove 2 items (uniqueItem1, uniqueItem2) from a nested array. As a result, I should get the filtered main object back without the two items. how do I do it?
const mainArray = {
country1: {
language1: ['item1', 'item2', 'item3'],
},
country2: {
language1: ['item1', 'item2', 'item3', 'item4'],
language2: ['item1', 'item2', 'item3', 'item4', 'item5'],
},
country3: {
language1: ['item1', 'item2', 'item3', **'uniqueItem1', 'uniqueItem2'**],
},
};
My result should be this:
const mainArray = {
country1: {
language1: ['item1', 'item2', 'item3'],
},
country2: {
language1: ['item1', 'item2', 'item3', 'item4'],
language2: ['item1', 'item2', 'item3', 'item4', 'item5'],
},
country3: {
language1: ['item1', 'item2', 'item3'],
},
};

const mainArray = {
country1: {
language1: ['item1', 'item2', 'item3','uniqueItem1'],
},
country2: {
language1: ['item1', 'item2', 'item3', 'item4'],
language2: ['item1', 'item2', 'item3', 'item4', 'item5'],
},
country3: {
language1: ['item1', 'item2', 'item3', 'uniqueItem1', 'uniqueItem2'],
},
};
const removeitems = ['uniqueItem1','uniqueItem2']
function removeItem(obj, itemtoberemoved){
for(let countrykey in obj) {
for(let langkey in obj[countrykey] ){
for(let removeVal of removeitems){
var curIndex = obj[countrykey][langkey].findIndex( (item) => item === removeVal );
if(curIndex > -1) {
obj[countrykey][langkey].splice(curIndex,1)
}
}
}
}
}
removeItem(mainArray, removeitems)
console.log(mainArray)

If you want to remove country specific item
const mainArray = {
country1: {
language1: ['item1', 'item2', 'item3','uniqueItem1'],
},
country2: {
language1: ['item1', 'item2', 'item3', 'item4'],
language2: ['item1', 'item2', 'item3', 'item4', 'item5'],
},
country3: {
language1: ['item1', 'item2', 'item3', 'uniqueItem1', 'uniqueItem2'],
},
};
/*country specific item remove*/
const removeitems = {
country : 'country3',
removeitems : ['uniqueItem1','uniqueItem2']
}
function removeItem(obj, itemtoberemoved){
for(let countrykey in obj) {
if( countrykey == itemtoberemoved.country ) {
for(let langkey in obj[countrykey] ){
for(let removeVal of itemtoberemoved.removeitems){
var curIndex = obj[countrykey][langkey].findIndex( (item) => item === removeVal );
if(curIndex > -1) {
obj[countrykey][langkey].splice(curIndex,1)
}
}
}
}
}
}
removeItem(mainArray, removeitems)
console.log(mainArray)

Related

How to sort time column in jsgrid?

We are binding a table using jqgrid. We have the first column start as a time column with a 12-hour format. We are facing an issue with sorting this data. The data is sorted correctly but it is not taking am/pm into consideration. Below is our code for binding the jqgrid:
var newFieldsArray =
[
{ name: "ID", title: "ID", type: "number", width: "50px", visible: false },
{
name: "TimeStart", title: "Start", type: "customTime", width: "100px", validate: "required",
sorttype: "date",
formatter : {
date : {
AmPm : ["am","pm","AM","PM"],
}
},
// datefmt: "m/d/Y h:i A",
//sorttype: 'datetime', formatter: 'date', formatoptions: {newformat: 'd/m/y', srcformat: 'Y-m-d H:i:s'},
insertTemplate: function () {
var $result = jsGrid.fields.customTime.prototype.insertTemplate.call(this); // original input
$result.val(varendTime);
return $result;
},
itemTemplate: function (value, item) {
return "<b style='display:none'>" + Date.parse(item.StartDate) + "</b><span>" + (item.TimeStart) + "</span>";
}
},
{
name: "TimeEnd", title: "End", type: "customTime", width: "100px", validate: "required",sorttype: "date", datefmt: "h:i"
},
{ name: "TimeTotal", title: "Time", type: "text", width: "50px", readOnly: true },
{
name: "CoilPO", title: "Coil PO", type: "text", width: "50px", validate: "required",
insertTemplate: function () {
var $result = jsGrid.fields.text.prototype.insertTemplate.call(this); // original input
$result.val(varlot);
return $result;
}
},
{ name: "Joints", title: "Joints", type: "integer", width: "60px" },
{ name: "CommercialGrade", title: "Commercial Grade", type: "integer", width: "80px" },
{ name: "QAHold", title: "QA Hold", type: "integer", width: "60px" },
{ name: "Rejected", title: "Reject", type: "integer", width: "60px" },
{ name: "ActionTaken", title: "Reason of Delay / Action Taken", type: "text", width: "120px" },
{
name: "ClassId", title: "Class",
type: "select", items: classDataArr,//classData.filter(function(n){return classdt.indexOf(n.Id) != -1 }),//classData,
valueField: "Id", textField: "Title",
insertTemplate: function () {
debugger;
var taxCategoryField = this._grid.fields[12];
var $insertControl = jsGrid.fields.select.prototype.insertTemplate.call(this);
var classId = 0;
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-insert").empty().append(taxCategoryField.insertTemplate());
$insertControl.on("change", function () {
debugger;
var classId = parseInt($(this).val());
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-insert").empty().append(taxCategoryField.insertTemplate());
});
return $insertControl;
},
editTemplate: function (value) {
var taxCategoryField = this._grid.fields[12];
var $editControl = jsGrid.fields.select.prototype.editTemplate.call(this, value);
var changeCountry = function () {
var classId = parseInt($editControl.val());
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-edit").empty().append(taxCategoryField.editTemplate());
};
debugger;
$editControl.on("change", changeCountry);
changeCountry();
return $editControl;
}
},
{
name: "VoiceId", title: "Voice", type: "select", items: voiceData,
valueField: "Id", textField: "Title", width: "120px", validate: "required",
insertcss: "tax-insert",
editcss: "tax-edit",
itemTemplate: function (teamId) {
var t = $.grep(voiceData, function (team) { return team.Id === teamId; })[0].Title;
return t;
},
},
{ name: "Remarks", title: "Remarks", type: "text", width: "110px" },
{ name: "control", type: "control" }
];
hoursGrid.jsGrid("option", "fields", newFieldsArray);
Below is two screenshots of data that appear when we sort:
Can someone tell me what we are doing wrong?
You're mixing up jsGrid and jqGrid. The way to achieve it in jsGrid is using the built-in sorter jsGrid.sortStrategies.date, I added an example below.
As commented by #Tomy Tomov (the creator of jqGrid), you're using jsGrid, not jqGrid. This is evident both by your code and by the UI in the screenshot.
Specifically, you took the date sorter of jqGrid and used it in your jsGrid code, but (of course) it's not supported there. You can go ahead and look in jsGrid source for AmPm which you used - and see it's not there.
So how to do it in jsGrid?
Just pass the built-in sorter jsGrid.sortStrategies.date to the sorter property. However, it does require Date objects, so if you only got time strings, you'll have to convert those to dates.
Below is a quick demo (jsfiddle), click the date column title to sort:
Note that getData gets a function parameter that is responsible to get all data as Date objects, and that the value of isUTC depends on whether you actually use it
$(document).ready(function () {
const dataFunc = getDataTimes;
$("#jsGrid").jsGrid({
width: "100%",
data: getData(dataFunc),
sorting: true,
fields: [{
name: "name",
type: "text",
width: 50
}, {
name: "date",
type: "date",
width: 50,
sorter: jsGrid.sortStrategies.date,
cellRenderer: (value, item) => {
const withYear = false;
const isUTC = dataFunc == getDataTimes;
return renderDateTime(value, item, withYear, isUTC);
}
}
]
});
});
function getData(getDates) {
const data = [
{name: "a"}, {name: "b"}, {name: "c"},
{name: "d"}, {name: "e"}, {name: "f"},
];
const dates = getDates();
for (let i = 0; i < dates.length; i++) {
data[i].date = dates[i];
}
return data;
}
function getDataDates() {
const date1 = new Date(2022, 10, 1, 4, 50);
const date2 = new Date(2022, 10, 1, 8, 50);
const date3 = new Date(2022, 10, 1, 15, 50);
const date4 = new Date(2021, 10, 1, 4, 50);
const date5 = new Date(2021, 10, 1, 8, 50);
const date6 = new Date(2021, 10, 1, 15, 50);
return [date1, date2, date3, date4, date5, date6];
}
function getDataTimes() {
const time1 = "3:50 AM";
const time2 = "8:50 AM";
const time3 = "4:50 AM";
const time4 = "3:50 PM";
const time5 = "8:50 PM";
const time6 = "4:50 PM";
const times = [time1, time2, time3, time4, time5, time6];
return times.map(t => convertTime12to24(t));
}
function convertTime12to24(time12h) {
const [time, modifier] = time12h.split(' ');
let [hours, minutes] = time.split(':');
if (modifier === 'PM') {
hours = parseInt(hours, 10) + 12;
}
return new Date(Date.UTC(2022,0,1,hours, minutes));
}
function renderDateTime(value, row, withYear, isUTC) {
return `<td>${getDateTimeAsString(value, withYear, isUTC)}</td>`;
}
function getDateTimeAsString(date, withYear, isUTC) {
var options = {
hour: 'numeric',
minute: 'numeric',
hour12: true
};
if (withYear) {
options.withYear = 'numeric';
}
if (isUTC) {
options.timeZone = 'UTC';
}
return date.toLocaleString('en-US', options);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" rel="stylesheet">
<div id="jsGrid" class="jsgrid"></div>
Let me give it a try, we have 2 options to perform Sorting operation in JsGrid:
1.Custom Field (Topic Name you can refer below link)
Reference Link :http://js-grid.com/docs/#grid-fields
In this, you can define custom property in your config and extend it.
You can use sorter property and call your user defined function werein you can logic to sort date with time stamps directly.
2.Sorting Strategies (Topic Name you can refer below link)
Reference Link :http://js-grid.com/docs/#grid-fields
In this, you can create your custom objects and then apply sorting strategies of date directly on to the object to perform sorting operation as per your logic.

Gatsby build ignores few images to copy into static folder

I have uploads folder with all my assets. When I run gatsby clean / gatsby build, it copies most of the images except 4 of them. It doesn't throw any error or warning as to what it ignores them. The same command on another docker container copies all of the images. The node/gatsby/npm and package.json are precisely the same on both containers. Am I missing something?
Package.json:
{
"name": "gatsby-starter-hello-world",
"private": true,
"description": "A simplified bare-bones starter for Gatsby",
"version": "0.1.0",
"license": "MIT",
"scripts": {
"build": "gatsby build",
"clean": "gatsby clean",
"develop": "gatsby develop -H 0.0.0.0",
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
"start": "npm run develop",
"refresh": "curl -X POST http://localhost:8000/__refresh",
"docker": "docker-compose -f docker-dev.yml up",
"serve": "gatsby serve -H 0.0.0.0 --port 8000",
"db:ql": "node graphql-server.js",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
},
"dependencies": {
"#apollo/react-hooks": "^3.1.2",
"#babel/runtime": "^7.8.4",
"#hot-loader/react-dom": "^16.11.0",
"#use-it/interval": "^0.1.3",
"apollo-boost": "^0.4.7",
"axios": "^0.19.0",
"body-scroll-lock": "^2.6.4",
"bootstrap": "^4.4.1",
"clsx": "^1.0.4",
"cross-env": "^6.0.3",
"final-form": "^4.18.5",
"final-form-calculate": "^1.3.1",
"final-form-set-field-data": "^1.0.2",
"gatsby": "^2.19.10",
"gatsby-image": "^2.2.39",
"gatsby-plugin-alias-imports": "^1.0.5",
"gatsby-plugin-client-side-redirect": "0.0.2",
"gatsby-plugin-lodash": "^3.1.19",
"gatsby-plugin-manifest": "^2.2.40",
"gatsby-plugin-minify-classnames": "^0.1.2",
"gatsby-plugin-offline": "^3.0.33",
"gatsby-plugin-polyfill-io": "^1.1.0",
"gatsby-plugin-react-axe": "^0.3.0",
"gatsby-plugin-react-helmet": "^3.1.21",
"gatsby-plugin-robots-txt": "^1.5.0",
"gatsby-plugin-s3": "^0.3.2",
"gatsby-plugin-sass": "^2.1.27",
"gatsby-plugin-sharp": "^2.4.4",
"gatsby-plugin-sitemap": "^2.2.27",
"gatsby-plugin-webpack-bundle-analyzer": "^1.0.5",
"gatsby-source-filesystem": "^2.1.47",
"gatsby-source-graphql": "^2.5.1",
"gatsby-source-wordpress": "^3.3.1",
"gatsby-transformer-sharp": "^2.3.13",
"gatsby-wordpress-inline-images": "^1.2.1",
"gatsby-wpgraphql-inline-images": "^0.2.5",
"graphql": "^14.6.0",
"graphql-tag": "^2.10.1",
"html-react-parser": "^0.10.0",
"install": "^0.13.0",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.15",
"lodash-es": "^4.17.15",
"moment": "^2.24.0",
"node-sass": "^4.13.0",
"prop-types": "^15.7.2",
"query-string": "^6.8.3",
"react": "^16.12.0",
"react-apollo": "^3.1.2",
"react-autosuggest": "^9.4.3",
"react-bootstrap": "^1.0.0-beta.16",
"react-calendar": "^2.19.2",
"react-datepicker": "^2.11.0",
"react-dates": "^21.8.0",
"react-dom": "^16.12.0",
"react-final-form": "^6.3.5",
"react-helmet": "^5.2.1",
"react-hotjar": "^2.2.0",
"react-icons": "^3.8.0",
"react-image-lightbox": "^5.1.1",
"react-payment-inputs": "^1.0.7",
"react-select": "^3.0.8",
"react-star-ratings": "^2.3.0",
"react-sticky": "^6.0.3",
"styled-components": "^4.4.1"
},
"devDependencies": {
"express": "^4.17.1",
"json-graphql-server": "^2.1.3",
"prettier": "^1.18.2"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
},
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
},
"browserslist": [
"> 2%",
"last 2 versions",
"IE 11"
],
"prettier": {
"tabWidth": 4,
"semi": false
},
"deploy": "gatsby-plugin-s3 deploy --yes"
}
gatsby-config:
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
const fs = require('fs')
const path = require("path")
const _ = require("lodash")
const axios = require("axios")
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
const rootPath = path.resolve(__dirname)
// https://gist.github.com/flipace/bed6b89aed5cb0e19cde
function replaceLocalhostBaseUrl(object) {
const newObject = _.clone(object);
_.each(object, (val, key) => {
if (typeof val === 'string' && /(http)(.*)(localhost)(:[0-9]{4})?/.test(val)) {
newObject[key] = val.replace(/(http)(.*)(localhost)(:[0-9]{4})?/, `https://${process.env.WEBSITE_DOMAIN}`)
} else if (typeof val === 'object') {
newObject[key] = replaceLocalhostBaseUrl(val)
} else {
newObject[key] = val
}
});
return newObject;
}
function replaceAbsoluteUrls(contentString){
const regex = /href\s*=\s*(['"])(https?:\/\/.+?)\1/ig
let link
let l
const getLocation = function(href){
let l = document.createElement("a")
l.href = href
return l
}
while((link = regex.exec(contentString)) !== null) {
//only replace urls where localhost or awesomenz.com is mentioned, like uat.awesomenz, dev.awesomenz
if (/localhost|dummy.co.nz/.test(link[2]))
{
l = getLocation(link[2])
contentString = contentString.replace(link[2],
// process.env.SITE_URL +
l.pathname +
"?" +l.href.substring( l.href.indexOf("?")+1 )
);
}
}
return contentString
}
function replaceImagesToLocalEnv(tg){
let fromUrl = "https://uat.dummy.co.nz"
if(process.env.ENV_TYPE == "build")
{
tg.url = tg.url.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.link = tg.link.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.icon = tg.icon.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes.thumbnail = tg.sizes.thumbnail.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes.medium = tg.sizes.medium.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes.medium_large = tg.sizes.medium_large.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes.large = tg.sizes.large.replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes['1536x1536'] = tg.sizes['1536x1536'].replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
tg.sizes['2048x2048'] = tg.sizes['2048x2048'].replace(fromUrl, process.env.MEDIA_BASE_SOURCE_URL)
}
return tg
}
const download_image = async (url, image_path) => {
const imagePathDir = path.dirname(image_path)
await fs.promises.mkdir(imagePathDir, { recursive: true }).catch(console.error);
return axios({
url,
responseType: 'stream',
}).then(
response =>
new Promise((resolve, reject) => {
response.data
.pipe(fs.createWriteStream(image_path))
.on('finish', () => resolve())
.on('error', e => reject(e));
}),
);
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
let wasOgDefaultImageDownloaded = false
let wasOgFrontpageImageDownloaded = false
async function downloadSocialImages(meta) {
if(meta.yoast_wpseo_facebook_image) {
const image = meta.yoast_wpseo_facebook_image
const imageUrl = new URL(image)
await download_image(image, path.join(rootPath, 'public', imageUrl.pathname))
}
if(meta.yoast_wpseo_twitter_image) {
const image = meta.yoast_wpseo_twitter_image
const imageUrl = new URL(image)
await download_image(image, path.join(rootPath, 'public', imageUrl.pathname))
}
if(!wasOgDefaultImageDownloaded && meta.yoast_wpseo_social_defaults.og_default_image) {
wasOgDefaultImageDownloaded = true
const image = meta.yoast_wpseo_social_defaults.og_default_image
const imageUrl = new URL(image)
await download_image(image, path.join(rootPath, 'public', imageUrl.pathname))
}
if(!wasOgFrontpageImageDownloaded && meta.yoast_wpseo_social_defaults.og_frontpage_image) {
wasOgFrontpageImageDownloaded = true
const image = meta.yoast_wpseo_social_defaults.og_frontpage_image
const imageUrl = new URL(image)
await download_image(image, path.join(rootPath, 'public', imageUrl.pathname))
}
}
module.exports = {
siteMetadata: {
title: `dummy`,
// siteUrl is hard coded for use in sitemap.xml (`gatsby-plugin-sitemap`)
siteUrl: process.env.SITE_URL,
},
plugins: [
{
resolve: 'gatsby-plugin-robots-txt',
options: {
host: process.env.SITE_URL,
sitemap: `${process.env.SITE_URL}/sitemap.xml`,
policy: [
{
userAgent: '*',
allow: '/',
disallow: [
'/cart',
'/checkout',
'/filter',
'/filter-tours',
'/manage-booking',
'/mydetails',
'/dev',
'/admin',
'/?flush',
]
},
]
}
},
{
resolve: `gatsby-plugin-polyfill-io`,
options: {
features: [`Array.prototype.find`, 'String.prototype.padStart'],
},
},
`gatsby-plugin-lodash`,
{
resolve: `gatsby-plugin-alias-imports`,
options: {
alias: {
// 'react-dom': '#hot-loader/react-dom',
"entrada-ui": path.join(rootPath, "src/entrada-ui"),
components: path.join(rootPath, "src/components"),
constants: path.join(rootPath, "src/constants"),
queries: path.join(rootPath, "src/queries"),
utils: path.join(rootPath, "src/utils"),
images: path.join(rootPath, "src/images"),
css: path.join(rootPath, "src/css"),
theme: path.join(rootPath, "src/theme"),
},
extensions: [],
},
},
{
resolve: "gatsby-plugin-sass",
options: {
cssLoaderOptions: {
camelCase: true,
},
},
},
{
resolve: `gatsby-plugin-minify-classnames`,
options: {
develop: false, // Enable/Disable on `gatsby develop`
},
},
// {
// resolve: "gatsby-source-graphql",
// options: {
// typeName: "PIH",
// fieldName: "pih",
// url: "https://api.dev.tourcatalogue.co.nz/supplier-graphql-api/query",
// // // HTTP headers
// // headers: {
// // // Learn about environment variables: https://gatsby.dev/env-vars
// // Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
// // },
// // // Additional options to pass to node-fetch
// // fetchOptions: {},
// },
// },
// {
// resolve: "gatsby-source-graphql",
// options: {
// typeName: "WP",
// fieldName: "wp",
// url: "http://localhost:4100/graphql",
// },
// },
// Wordpress
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
// {
// resolve: `gatsby-plugin-manifest`,
// options: {
// name: `gatsby-starter-default`,
// short_name: `starter`,
// start_url: `/`,
// background_color: `#663399`,
// theme_color: `#663399`,
// display: `minimal-ui`,
// icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
// crossOrigin: `use-credentials`,
// },
// },
{
resolve: "gatsby-source-wordpress",
options: {
baseUrl: `${process.env.WORDPRESS_URL}`,
protocol: `${process.env.WP_PROTOCOL}`,
plugins: [
{
resolve: `gatsby-wordpress-inline-images`,
options: {
baseUrl: `${process.env.WORDPRESS_URL}`,
protocol: `${process.env.WP_PROTOCOL}`
// baseUrl: `uat.dummy.co.nz`,
// protocol: `https`
}
}
],
// TODO: Need to have further testing
// searchAndReplaceContentUrls: {
// sourceUrl: `${process.env.SITE_URL}`,
// replacementUrl: "",
// },
hostingWPCOM: false,
useACF: true,
acfOptionPageIds: [],
verboseOutput: false,
perPage: 100,
// Set how many simultaneous requests are sent at once.
concurrentRequests: 10,
includedRoutes: [
"**/categories",
"**/posts",
"**/pages",
"**/media",
"**/tags",
"**/tours",
"**/destinations",
"**/themes",
"**/taxonomies",
"**/announcements",
"**/*/*/menus", // <== Menu api endpoint
"**/*/*/menu-locations", // <== Menu api endpoint
"**/exposeredirections", // <== Exposeredirections api endpoint
],
excludedRoutes: [],
normalizers: normalizers => {
return _.compact([
process.env.MEDIA_BASE_SOURCE_URL ?
{
name: `changeMediaSourceUrls`,
normalizer: async ({
entities,
}) => (
entities.map((entity) => {
if(entity.content && entity.content !== ""){
entity.content = replaceAbsoluteUrls(entity.content)
}
///////////////////////////////////////////////////////////
if(entity.acf)
{
if(entity.acf.gallery)
{
let nLoop = entity.acf.gallery.length
if( nLoop > 0)
{
let tempGallery = []
for(let c=0; c<nLoop; c++){
tempGallery.push( replaceImagesToLocalEnv(entity.acf.gallery[c]) )
}
entity.acf.gallery = tempGallery
}
}
if(entity.acf.card_image)
{
entity.acf.card_image = replaceImagesToLocalEnv(entity.acf.card_image)
}
if(entity.acf.card_map)
{
entity.acf.card_map = replaceImagesToLocalEnv(entity.acf.card_map)
}
if(entity.acf.image)
{
entity.acf.image = replaceImagesToLocalEnv(entity.acf.image)
}
if(entity.acf.info_cards)
{
let nLoop = entity.acf.info_cards.length
if( nLoop > 0)
{
let tempCardsInfo = []
let tmp
for(let c=0; c<nLoop; c++){
tmp = entity.acf.info_cards[c]
tmp.card_image = replaceImagesToLocalEnv(tmp.card_image)
tempCardsInfo.push( tmp )
}
entity.acf.info_cards = tempCardsInfo
}
}
}
///////////////////////////////////////////////////////////
if(entity.__type === 'wordpress__wp_media') {
// Transforms:
// https://uat.dummy.co.nz/wp-content/uploads/2020/01/Placeholder-Image.png
// into:
// http://localhost/wp-content/uploads/2020/01/Placeholder-Image.png
entity.source_url = `${process.env.MEDIA_BASE_SOURCE_URL}/${entity.source_url.split("/").slice(3).join('/')}`
} else if (entity.yoast_meta) {
downloadSocialImages(entity.yoast_meta)
entity.yoast_meta.yoast_schema = typeof entity.yoast_meta.yoast_schema === 'string' ? JSON.parse(entity.yoast_meta.yoast_schema) : entity.yoast_meta.yoast_schema
entity.yoast_meta = replaceLocalhostBaseUrl(entity.yoast_meta)
entity.yoast_meta.yoast_schema = JSON.stringify(entity.yoast_meta.yoast_schema)
}
return entity
})
)
} : undefined,
...normalizers
])
},
},
},
// {
// resolve: 'gatsby-wpgraphql-inline-images',
// options: {
// wordPressUrl: process.env.MEDIA_BASE_SOURCE_URL+'/',
// uploadsUrl: process.env.MEDIA_BASE_SOURCE_URL+'/wp-content/uploads/',
// processPostTypes: ['Page', 'Post', 'CustomPost'],
// graphqlTypeName: 'WPGraphQL',
// httpHeaders: {
// Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
// }
// },
// },
{
resolve: `gatsby-plugin-s3`,
options: {
bucketName: 'static-dummy'
},
},
{
resolve: `gatsby-plugin-sitemap`,
options: {
// See: https://github.com/isaacs/minimatch
// The example below will exclude the single `path/to/page` and all routes beginning with `category`
query: `
{
site {
siteMetadata {
siteUrl
}
}
allSitePage {
edges {
node {
path
}
}
}
}`,
serialize: ({ site, allSitePage }) =>
allSitePage.edges.map(edge => {
return {
url: site.siteMetadata.siteUrl + edge.node.path,
changefreq: `daily`,
priority: 0.7,
}
})
}
},
`gatsby-plugin-client-side-redirect`, // keep it in last in list,
// {
// resolve: 'gatsby-plugin-react-axe',
// options: {
// // Integrate react-axe in production. This defaults to false.
// showInProduction: false,
// },
// },
// {
// resolve: 'gatsby-plugin-webpack-bundle-analyzer',
// options: {
// analyzerPort: 8888,
// production: true,
// },
// }
],
}
env file:
# If you are running `npm run build` in your local, you need to add the port :8080
# to WORDPRESS_URL and MEDIA_BASE_SOURCE_URL
WORDPRESS_URL=localhost
MEDIA_BASE_SOURCE_URL=http://localhost
WP_POD_PUBLIC_URL=https://uat.dummy.co.nz
WP_PROTOCOL=http
ENV_TYPE=build
WEBSITE_DOMAIN=uat.dummy.co.nz
SITE_URL=https://www.uat.dummy.co.nz
GATSBY_CPU_COUNT=logical_cores

Javascript - refactor array - array reduce

What is the best way to refactor(ise) an array / array of objects ?
I was thinking of using array.reduce, but could not figure out a solution.
for example, transform this array :
const carsInput =
[
{
brand: 'volkswagen',
model: 'golf',
motorSpec: {
...
},
Dim: {
...
},
},
...
{
brand: 'volkswagen',
model: 'passat',
motorSpec: {
...
},
Dim: {
...
},
},
]
to this array of objects
const carsOutput =
{
volkswagen: {
brandName: 'volkswagen',
models: {
golf: {
modelName: 'golf',
motorSpec: {
...
},
Dim: {
...
},
},
passat: {
modelName: 'passat',
motorSpec: {
...
},
Dim: {
...
},
},
},
},
}
Also if you think of another (better) way of presenting this array of objects, I am all ears !
Thanks a lot
I am sure others have more concise ways of doing this but here is one approach.
const carsInput =
[{
brand: 'ford',
model: 'mustang',
motorSpec: {
},
Dim: {
}
},
{
brand: 'volkswagen',
model: 'golf',
motorSpec: {
},
Dim: {
}
},
{
brand: 'volkswagen',
model: 'passat',
motorSpec: {
},
Dim: {
}
},
];
const carsOutput = new Object();
function initializeMake(makeName) {
carsOutput[makeName] = { brandName: makeName, models: {}};
return carsOutput[makeName]
}
carsInput.forEach(car => {
let make = carsOutput[car.brand] || initializeMake(car.brand);
const modelDefinition = {
'modelName': car['model'],
'motorSpec': car.motorSpec,
'Dim': car.Dim
};
make.models[car.model] = modelDefinition;
});
console.log(carsOutput)

Kendo UI for Angular Exporting selected rows to Excel

I'm using Kendo UI for Angular and I am trying to export my grid to Excel. I have implemented a solution like this: https://www.telerik.com/kendo-angular-ui/components/grid/export/excel-export/
and it does work. It exports all rows in my grid. My problem is that I only want to export selected rows. I haven't been able to successfully filter the allData method to only export selected rows.
It looks to me like the process method called from within the allData method can take a State object that has a filter: component. But for the life of me I can't seem to get it to work. Can anybody point me to a simple example where the selected rows only are exported to Excel?
Thanks,
John B.
I have implemented selected rows and selection key to be entire row so that when I export i can retrieve the selected rows and modified export allData to export selection data if exists.If selection doesnot exists then exports all data.
public mySelectionKey(context: RowArgs): string {
// return context.dataItem.serialNumber + " " + context.index;
return context.dataItem;
}
public allData(): ExcelExportData {
let selInventory: Inventory[] = [];
let result: ExcelExportData;
selInventory = JSON.parse(JSON.stringify(this.mySelection));
if (selInventory.length > 0) {
result = {
data: process(selInventory, {
sort: [{ field: "serialNumber", dir: "asc" }]
}).data
};
} else {
result = {
data: process(this.inventoryData, {
sort: [{ field: "serialNumber", dir: "asc" }]
}).data
};
}
return result;
}
Export selected or all rows
function excelExport() {
var exportAll = $('.selectrow').is(":checked");
var grid = $("#grid");
var rows = [{
cells: [
{ value: "column1" },
{ value: "column2" },
{ value: "column3" },
{ value: "column4" },
{ value: "column5" },
{ value: "column6" },
{ value: "column7" }
]
}];
if (exportAll) {
var dataDource = grid.getKendoGrid();
var trs = $("#grid").find('tr');
for (var i = 0; i < trs.length; i++) {
if ($(trs[i]).find(":checkbox").is(":checked")) {
var dataItem = dataDource.dataItem(trs[i]);
rows.push({
cells: [
{ value: dataItem.column1 },
{ value: dataItem.column2 },
{ value: dataItem.column3 },
{ value: dataItem.column4 },
{ value: dataItem.column5 },
{ value: dataItem.column6 },
{ value: dataItem.column7 }
]
})
}
}
}
else {
var dataSource = grid.data("kendoGrid").dataSource;
var trs = grid.find('tr');
for (var i = 1; i < dataSource._data.length; i++) {
var dataItem = dataSource._data[i];
rows.push({
cells: [
{ value: dataItem.column1 },
{ value: dataItem.column2 },
{ value: dataItem.column3 },
{ value: dataItem.column4 },
{ value: dataItem.column5 },
{ value: dataItem.column6 },
{ value: dataItem.column7 }
]
})
}
}
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: [
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true }
],
title: "Exported Result",
rows: rows
}
]
});
kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: "ExportedResult" });
}

Using Multiselect in row filter, kendo ui grid

Below is a sample of integrating multiselect with kendo ui filter row.
http://dojo.telerik.com/eriMA
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
autoBind:true,
columns: [
{
field: "color",
filterable: {
cell: {
template: function (args) {
// create a MultiselectList of unique values (colors)
args.element.kendoMultiSelect({
dataSource: args.dataSource,
dataTextField: "color",
dataValueField: "color",
valuePrimitive: true,
// tagMode: true
});
},
showOperators: false
}
}
},
{ field: "age" } ],
filterable: { mode: "row" },
dataSource: { data: [ { color: "#ff0000", age: 30 }, { color: "#000000", age: 33 }], requestStart: onRequestStart }});
function onRequestStart(e){
var filter = e.sender.filter();
if (filter && filter.filters && filter.filters.length > 0) {
var filter1 = filter.filters;
for (var i = 0; i < filter1.length; i++) {
if (filter1[i].field == "color" && filter1[i].value) {
var colorList = filter1[i].value.split(",");
if (colorList.length > 0) {
var newFilter = { logic: "or", filters: [] };
for (var k = 0; k < colorList.length; k++) {
newFilter.filters.push({ field: "color", operator: "eq", value: colorList[k] });
}
filter1 = filter1.splice(i, 1, newFilter);
e.preventDefault();
e.sender.filter(filter);
}
}
}
}
}
</script>
Now, I want to set a default filter for the grid. For that I have created another sample.
http://dojo.telerik.com/eriMA/2
But unfortunately, if the grid dataSource data is initially empty, the multiselect value gets reset with first value. However, the data is filtered correctly. Can somebody help to overcome this limitation.
I have identified that somehow the filter cell get cleared after the dataBound event, if the dataSource is emtpy. So I set the value back using a timeout.
here is the link to updated source. http://dojo.telerik.com/eriMA/7
<div id="grid"></div>
<script>
var colorMulti = null;
var grid = $("#grid").kendoGrid({
autoBind:false,
columns: [
{
field: "ShipCity",
filterable: {
cell: {
template: function (args) {
// create a MultiselectList of unique values (colors)
colorMulti =args.element.kendoMultiSelect({
dataSource: {data : ["Lyon","Graz","Bern"]},
valuePrimitive: true,
// tagMode: true
}).data("kendoMultiSelect");
},
showOperators: false
}
}
},
{ field: "OrderID" } ],
filterable: { mode: "row" },
dataSource: {
type: "odata",
transport: {
read: "//demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: { type: "number" },
Freight: { type: "number" },
ShipName: { type: "string" },
OrderDate: { type: "date" },
ShipCity: { type: "string" }
}
}
},
pageSize: 20,
requestStart:onRequestStart
},
dataBound: onDataBound
}).data("kendoGrid");
function onRequestStart(e){
var filter = e.sender.filter();
if (filter && filter.filters && filter.filters.length > 0) {
var filter1 = filter.filters;
for (var i = 0; i < filter1.length; i++) {
if (filter1[i].field == "ShipCity" && filter1[i].value) {
var colorList = filter1[i].value.split(",");
if (colorList.length > 0) {
var newFilter = { logic: "or", filters: [] };
for (var k = 0; k < colorList.length; k++) {
newFilter.filters.push({ field: "ShipCity", operator: "eq", value: colorList[k] });
}
filter1 = filter1.splice(i, 1, newFilter);
e.preventDefault();
e.sender.filter(filter);
}
}
}
}
}
function onDataBound(e){
var multiSelectValue = [];
var filter = grid.dataSource.filter();
if (filter && filter.filters && filter.filters.length > 0) {
var filter1 = filter.filters;
for (var i = 0; i < filter1.length; i++) {
if (filter1[i].field == "ShipCity" && filter1[i].value) {
multiSelectValue.push(filter1[i].value);
} else if (filter1[i].filters && filter1[i].filters.length > 0 && filter1[i].logic == "or") {
var filter2 = filter1[i].filters;
var multiSelectValue = [];
for (var j = 0; j < filter2.length; j++) {
if (filter2[j].field == "ShipCity") {
multiSelectValue.push(filter2[j].value);
}
}
}
}
}
setTimeout(function () { colorMulti.value(multiSelectValue) });
}
$(document).ready(function () {
grid.dataSource.filter({ "filters": [{ "operator": "eq", "value": "Lyon,Graz,Bern", "field": "ShipCity" }], "logic": "and" });
});
</script>

Resources