@c8y/ngx-components 1023.80.2 → 1023.81.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -140,12 +140,16 @@ class StaticAssetsService {
140
140
  * Gets the static assets app for the given type.
141
141
  */
142
142
  async getAppForTenant(type) {
143
- const appName = this.getContextPath(type, false);
144
- const { data: apps } = await this.appService.listByName(appName);
145
- if (!apps.length) {
146
- throw Error(`No app with name ${appName} found.`);
143
+ const contextPath = this.getContextPath(type);
144
+ const { data: manifest } = await this.appService.getManifestOfContextPath(contextPath);
145
+ if (!manifest.id) {
146
+ throw Error(`No app with path ${contextPath} found.`);
147
147
  }
148
- return apps[0];
148
+ const { data: app } = await this.appService.detail(manifest.id);
149
+ if (app.owner?.tenant.id !== this.appstate.currentTenant.value?.name) {
150
+ throw Error(`No app with path ${contextPath} found that is owned by the current tenant.`);
151
+ }
152
+ return app;
149
153
  }
150
154
  getContentJSONForType(type, appendTenantId) {
151
155
  const path = this.getPathForContent(type, appendTenantId);
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-static-assets-data.mjs","sources":["../../static-assets/data/static-assets.service.ts","../../static-assets/data/c8y-ngx-components-static-assets-data.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { ApplicationAvailability, ApplicationType, FetchClient, IApplication } from '@c8y/client';\nimport { ApplicationService } from '@c8y/client';\nimport { AppStateService, DroppedFile, FilesService, ZipService } from '@c8y/ngx-components';\nimport { StaticAsset, StaticAssetType } from './static-assets.model';\n\n@Injectable({ providedIn: 'root' })\nexport class StaticAssetsService {\n readonly fileNames = {\n contents: 'contents.json',\n manifest: 'cumulocity.json',\n exportZipName: 'static-assets.zip'\n } as const;\n private listFilesCachePromises: Record<string, Promise<StaticAsset[]>> = {};\n\n constructor(\n private appstate: AppStateService,\n private appService: ApplicationService,\n private fetchClient: FetchClient,\n private fileService: FilesService,\n private zip: ZipService\n ) {}\n\n /**\n * Lists all files of the given type.\n * Forces a cache renewal.\n */\n async listFiles<T extends string = StaticAssetType>(type: T): Promise<StaticAsset[]> {\n return this.listFilesCached(type, true);\n }\n\n /**\n * Lists all files of the given type.\n * Uses a cache.\n */\n async listFilesCached<T extends string = StaticAssetType>(\n type: T,\n forceCacheRenewal = false\n ): Promise<StaticAsset[]> {\n if (!this.listFilesCachePromises[type] || forceCacheRenewal) {\n this.listFilesCachePromises[type] = this._listFiles(type);\n }\n\n return await this.listFilesCachePromises[type];\n }\n\n /**\n * Clones all assets of the given type from parent tenants into the current tenant.\n */\n async cloneAssetsIntoTenant<T extends string = StaticAssetType>(type: T) {\n const { data: apps } = await this.appService.list({\n availability: ApplicationAvailability.SHARED,\n type: ApplicationType.HOSTED,\n pageSize: 2000\n });\n\n const tenantIdsFromOtherAssetApps = apps\n .filter(app => {\n const result =\n app.owner?.tenant?.id &&\n app.owner?.tenant?.id !== this.appstate.currentTenant.value?.name &&\n app.contextPath === this.getContextPath(type, app.owner?.tenant?.id);\n return result;\n })\n .map(app => app.owner?.tenant?.id);\n\n let filesOfCurrentTenant = await this._listFiles(type);\n\n let filesToUpload = new Array<File>();\n\n const oldAssets = new Array<StaticAsset>();\n\n for (const tenantId of tenantIdsFromOtherAssetApps) {\n try {\n const filesOfApp = await this.getContentJSONForType(type, tenantId);\n oldAssets.push(...filesOfApp);\n for (const file of filesOfApp) {\n try {\n const response = await this.fetchClient.fetch(file.path);\n if (response.status !== 200) {\n console.warn(`Failed to get file \"${file.fileName}\" from path ${file.path}`);\n continue;\n }\n const fileContent = await response.blob();\n\n // remove existing file with same name\n filesOfCurrentTenant = filesOfCurrentTenant.filter(\n existingFile => existingFile.fileName !== file.fileName\n );\n filesToUpload = filesToUpload.filter(\n existingFile => existingFile.name !== file.fileName\n );\n\n filesToUpload.push(new File([fileContent], file.fileName, { type: file.type }));\n } catch (e) {\n console.warn(`Failed to add file \"${file.fileName}\" from tenant ${tenantId}`, e);\n }\n }\n } catch (e) {\n console.warn(`Failed to get asset files from tenant ${tenantId}`);\n }\n }\n\n if (!filesToUpload.length) {\n return;\n }\n\n const newAssets = await this.addFilesToStaticAssets(type, filesToUpload, filesOfCurrentTenant);\n\n return { oldAssets, newAssets };\n }\n\n /**\n * Adds the given files to the static assets of the given type.\n */\n async addFilesToStaticAssets<T extends string = StaticAssetType>(\n type: T,\n files: DroppedFile[] | File[],\n existingFiles: StaticAsset[],\n throwErrorOnExistingFiles = true\n ) {\n const app = await this.getAppForTenant(type);\n const filesToAddToContents = new Array<StaticAsset>();\n const addedAt = new Date().toISOString();\n const filesToUpload: {\n path: string;\n contents: Blob;\n }[] = [];\n for (const droppedFile of files) {\n const file = droppedFile instanceof File ? droppedFile : droppedFile.file;\n const fileName = file.name.toLowerCase().replace(/[^a-zA-Z0-9\\-\\_\\.]/g, '');\n const newFile = new File([file], fileName, {\n type: file.type,\n lastModified: file.lastModified\n });\n if (existingFiles.find(existingFile => existingFile.fileName === fileName)) {\n if (throwErrorOnExistingFiles) {\n throw Error(`File with name \"${fileName}\" is already existing.`);\n }\n existingFiles = existingFiles.filter(existingFile => existingFile.fileName !== fileName);\n }\n const fileExtension = file.name.split('.').pop();\n filesToAddToContents.push({\n addedAt,\n lastModified: file.lastModified,\n extension: fileExtension,\n fileName: fileName,\n originalFileName: file.name,\n path: `/apps/public/${app.contextPath}/${fileName}`,\n size: newFile.size,\n type: newFile.type,\n hashSum: await this.fileService.getHashSumOfFile(newFile)\n });\n filesToUpload.push({\n contents: newFile,\n path: fileName\n });\n }\n\n const newFiles: StaticAsset[] = [...existingFiles, ...filesToAddToContents];\n filesToUpload.push({\n contents: new File([JSON.stringify(newFiles)], this.fileNames.contents, {\n type: 'application/json'\n }),\n path: this.fileNames.contents\n });\n await this.appService.binary(app).updateFiles(filesToUpload);\n await this.ensureAddedFilesArePresent(filesToAddToContents);\n return newFiles;\n }\n\n /**\n * Gets the static assets app for the given type.\n */\n async getAppForTenant<T extends string = StaticAssetType>(type: T): Promise<IApplication> {\n const appName = this.getContextPath(type, false);\n const { data: apps } = await this.appService.listByName(appName);\n if (!apps.length) {\n throw Error(`No app with name ${appName} found.`);\n }\n return apps[0];\n }\n\n private getContentJSONForType<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ) {\n const path = this.getPathForContent(type, appendTenantId);\n return this.getContentJSONFromPath(path);\n }\n\n private async getContentJSONFromPath(path: string): Promise<StaticAsset[]> {\n const response = await this.fetchClient.fetch(path);\n if (response.status !== 200) {\n throw Error(`Failed to retrieve ${path}`);\n }\n\n const content = await response.json();\n return content;\n }\n\n private async ensureAddedFilesArePresent(files: StaticAsset[]) {\n for (const file of files) {\n await this.ensureFileIsPresent(file);\n }\n }\n\n private async ensureFileIsPresent(file: StaticAsset) {\n for (let i = 0; i < 12; i++) {\n try {\n const currentDate = new Date();\n const response = await this.fetchClient.fetch(\n `${file.path}?nocache=${currentDate.getTime()}`\n );\n if (response.status !== 200) {\n await this.sleep(5_000);\n continue;\n }\n\n const blob = await response.blob();\n const hashSum = await this.fileService.getHashSumOfFile(blob);\n if (hashSum !== file.hashSum) {\n await this.sleep(5_000);\n continue;\n }\n return;\n } catch (e) {\n console.warn(e);\n continue;\n }\n }\n throw Error(`Unable to retrieve file from ${file.path}`);\n }\n\n private sleep(duration: number): Promise<void> {\n return new Promise<void>(resolve => setTimeout(() => resolve(), duration));\n }\n\n private async _listFiles<T extends string = StaticAssetType>(type: T) {\n try {\n const files = await this.getContentJSONForType(type);\n return files;\n } catch (e) {\n console.warn(e);\n }\n\n return await this.createEmptyApp(type);\n }\n\n private getPathForContent<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ): string {\n const currentDate = new Date();\n const contextPath = this.getContextPath(type, appendTenantId);\n return `/apps/public/${contextPath}/${\n this.fileNames.contents\n }?nocache=${currentDate.getTime()}`;\n }\n\n private getContextPath<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | false | undefined\n ) {\n let contextPath: string = type + '-assets';\n const tenantId =\n appendTenantId === undefined ? this.appstate.currentTenant.value?.name : appendTenantId;\n if (tenantId) {\n contextPath = `${contextPath}-${tenantId}`;\n }\n return contextPath;\n }\n\n private async createEmptyApp<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ): Promise<StaticAsset[]> {\n const name = this.getContextPath(type, false);\n const contextPath = this.getContextPath(type, appendTenantId);\n const key = `${contextPath}-key`;\n const manifest: IApplication = {\n name,\n contextPath,\n key,\n description: `Application containing static assets used for ${type}.`,\n noAppSwitcher: true,\n type: ApplicationType.HOSTED,\n availability: ApplicationAvailability.MARKET\n };\n\n const content = [];\n const zipFile = await this.zip.createZip([\n {\n fileName: `${this.fileNames.manifest}`,\n blob: new Blob([JSON.stringify(manifest)])\n },\n {\n fileName: `${this.fileNames.contents}`,\n blob: new Blob([JSON.stringify(content)])\n }\n ]);\n const { data: app } = await this.appService.create(manifest);\n const { data: appBinary } = await this.appService\n .binary(app)\n .upload(zipFile, `empty-${name}.zip`);\n await this.appService.update({ id: app.id, activeVersionId: appBinary.id as string });\n return [];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-static-assets-data.mjs","sources":["../../static-assets/data/static-assets.service.ts","../../static-assets/data/c8y-ngx-components-static-assets-data.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport {\n ApplicationAvailability,\n ApplicationService,\n ApplicationType,\n FetchClient,\n IApplication\n} from '@c8y/client';\nimport { AppStateService, DroppedFile, FilesService, ZipService } from '@c8y/ngx-components';\nimport { StaticAsset, StaticAssetType } from './static-assets.model';\n\n@Injectable({ providedIn: 'root' })\nexport class StaticAssetsService {\n readonly fileNames = {\n contents: 'contents.json',\n manifest: 'cumulocity.json',\n exportZipName: 'static-assets.zip'\n } as const;\n private listFilesCachePromises: Record<string, Promise<StaticAsset[]>> = {};\n\n constructor(\n private appstate: AppStateService,\n private appService: ApplicationService,\n private fetchClient: FetchClient,\n private fileService: FilesService,\n private zip: ZipService\n ) {}\n\n /**\n * Lists all files of the given type.\n * Forces a cache renewal.\n */\n async listFiles<T extends string = StaticAssetType>(type: T): Promise<StaticAsset[]> {\n return this.listFilesCached(type, true);\n }\n\n /**\n * Lists all files of the given type.\n * Uses a cache.\n */\n async listFilesCached<T extends string = StaticAssetType>(\n type: T,\n forceCacheRenewal = false\n ): Promise<StaticAsset[]> {\n if (!this.listFilesCachePromises[type] || forceCacheRenewal) {\n this.listFilesCachePromises[type] = this._listFiles(type);\n }\n\n return await this.listFilesCachePromises[type];\n }\n\n /**\n * Clones all assets of the given type from parent tenants into the current tenant.\n */\n async cloneAssetsIntoTenant<T extends string = StaticAssetType>(type: T) {\n const { data: apps } = await this.appService.list({\n availability: ApplicationAvailability.SHARED,\n type: ApplicationType.HOSTED,\n pageSize: 2000\n });\n\n const tenantIdsFromOtherAssetApps = apps\n .filter(app => {\n const result =\n app.owner?.tenant?.id &&\n app.owner?.tenant?.id !== this.appstate.currentTenant.value?.name &&\n app.contextPath === this.getContextPath(type, app.owner?.tenant?.id);\n return result;\n })\n .map(app => app.owner?.tenant?.id);\n\n let filesOfCurrentTenant = await this._listFiles(type);\n\n let filesToUpload = new Array<File>();\n\n const oldAssets = new Array<StaticAsset>();\n\n for (const tenantId of tenantIdsFromOtherAssetApps) {\n try {\n const filesOfApp = await this.getContentJSONForType(type, tenantId);\n oldAssets.push(...filesOfApp);\n for (const file of filesOfApp) {\n try {\n const response = await this.fetchClient.fetch(file.path);\n if (response.status !== 200) {\n console.warn(`Failed to get file \"${file.fileName}\" from path ${file.path}`);\n continue;\n }\n const fileContent = await response.blob();\n\n // remove existing file with same name\n filesOfCurrentTenant = filesOfCurrentTenant.filter(\n existingFile => existingFile.fileName !== file.fileName\n );\n filesToUpload = filesToUpload.filter(\n existingFile => existingFile.name !== file.fileName\n );\n\n filesToUpload.push(new File([fileContent], file.fileName, { type: file.type }));\n } catch (e) {\n console.warn(`Failed to add file \"${file.fileName}\" from tenant ${tenantId}`, e);\n }\n }\n } catch (e) {\n console.warn(`Failed to get asset files from tenant ${tenantId}`);\n }\n }\n\n if (!filesToUpload.length) {\n return;\n }\n\n const newAssets = await this.addFilesToStaticAssets(type, filesToUpload, filesOfCurrentTenant);\n\n return { oldAssets, newAssets };\n }\n\n /**\n * Adds the given files to the static assets of the given type.\n */\n async addFilesToStaticAssets<T extends string = StaticAssetType>(\n type: T,\n files: DroppedFile[] | File[],\n existingFiles: StaticAsset[],\n throwErrorOnExistingFiles = true\n ) {\n const app = await this.getAppForTenant(type);\n const filesToAddToContents = new Array<StaticAsset>();\n const addedAt = new Date().toISOString();\n const filesToUpload: {\n path: string;\n contents: Blob;\n }[] = [];\n for (const droppedFile of files) {\n const file = droppedFile instanceof File ? droppedFile : droppedFile.file;\n const fileName = file.name.toLowerCase().replace(/[^a-zA-Z0-9\\-\\_\\.]/g, '');\n const newFile = new File([file], fileName, {\n type: file.type,\n lastModified: file.lastModified\n });\n if (existingFiles.find(existingFile => existingFile.fileName === fileName)) {\n if (throwErrorOnExistingFiles) {\n throw Error(`File with name \"${fileName}\" is already existing.`);\n }\n existingFiles = existingFiles.filter(existingFile => existingFile.fileName !== fileName);\n }\n const fileExtension = file.name.split('.').pop();\n filesToAddToContents.push({\n addedAt,\n lastModified: file.lastModified,\n extension: fileExtension,\n fileName: fileName,\n originalFileName: file.name,\n path: `/apps/public/${app.contextPath}/${fileName}`,\n size: newFile.size,\n type: newFile.type,\n hashSum: await this.fileService.getHashSumOfFile(newFile)\n });\n filesToUpload.push({\n contents: newFile,\n path: fileName\n });\n }\n\n const newFiles: StaticAsset[] = [...existingFiles, ...filesToAddToContents];\n filesToUpload.push({\n contents: new File([JSON.stringify(newFiles)], this.fileNames.contents, {\n type: 'application/json'\n }),\n path: this.fileNames.contents\n });\n await this.appService.binary(app).updateFiles(filesToUpload);\n await this.ensureAddedFilesArePresent(filesToAddToContents);\n return newFiles;\n }\n\n /**\n * Gets the static assets app for the given type.\n */\n async getAppForTenant<T extends string = StaticAssetType>(type: T): Promise<IApplication> {\n const contextPath = this.getContextPath(type);\n\n const { data: manifest } = await this.appService.getManifestOfContextPath(contextPath);\n if (!manifest.id) {\n throw Error(`No app with path ${contextPath} found.`);\n }\n const { data: app } = await this.appService.detail(manifest.id);\n if (app.owner?.tenant.id !== this.appstate.currentTenant.value?.name) {\n throw Error(`No app with path ${contextPath} found that is owned by the current tenant.`);\n }\n return app;\n }\n\n private getContentJSONForType<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ) {\n const path = this.getPathForContent(type, appendTenantId);\n return this.getContentJSONFromPath(path);\n }\n\n private async getContentJSONFromPath(path: string): Promise<StaticAsset[]> {\n const response = await this.fetchClient.fetch(path);\n if (response.status !== 200) {\n throw Error(`Failed to retrieve ${path}`);\n }\n\n const content = await response.json();\n return content;\n }\n\n private async ensureAddedFilesArePresent(files: StaticAsset[]) {\n for (const file of files) {\n await this.ensureFileIsPresent(file);\n }\n }\n\n private async ensureFileIsPresent(file: StaticAsset) {\n for (let i = 0; i < 12; i++) {\n try {\n const currentDate = new Date();\n const response = await this.fetchClient.fetch(\n `${file.path}?nocache=${currentDate.getTime()}`\n );\n if (response.status !== 200) {\n await this.sleep(5_000);\n continue;\n }\n\n const blob = await response.blob();\n const hashSum = await this.fileService.getHashSumOfFile(blob);\n if (hashSum !== file.hashSum) {\n await this.sleep(5_000);\n continue;\n }\n return;\n } catch (e) {\n console.warn(e);\n continue;\n }\n }\n throw Error(`Unable to retrieve file from ${file.path}`);\n }\n\n private sleep(duration: number): Promise<void> {\n return new Promise<void>(resolve => setTimeout(() => resolve(), duration));\n }\n\n private async _listFiles<T extends string = StaticAssetType>(type: T) {\n try {\n const files = await this.getContentJSONForType(type);\n return files;\n } catch (e) {\n console.warn(e);\n }\n\n return await this.createEmptyApp(type);\n }\n\n private getPathForContent<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ): string {\n const currentDate = new Date();\n const contextPath = this.getContextPath(type, appendTenantId);\n return `/apps/public/${contextPath}/${\n this.fileNames.contents\n }?nocache=${currentDate.getTime()}`;\n }\n\n private getContextPath<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | false | undefined\n ) {\n let contextPath: string = type + '-assets';\n const tenantId =\n appendTenantId === undefined ? this.appstate.currentTenant.value?.name : appendTenantId;\n if (tenantId) {\n contextPath = `${contextPath}-${tenantId}`;\n }\n return contextPath;\n }\n\n private async createEmptyApp<T extends string = StaticAssetType>(\n type: T,\n appendTenantId?: string | null | undefined\n ): Promise<StaticAsset[]> {\n const name = this.getContextPath(type, false);\n const contextPath = this.getContextPath(type, appendTenantId);\n const key = `${contextPath}-key`;\n const manifest: IApplication = {\n name,\n contextPath,\n key,\n description: `Application containing static assets used for ${type}.`,\n noAppSwitcher: true,\n type: ApplicationType.HOSTED,\n availability: ApplicationAvailability.MARKET\n };\n\n const content = [];\n const zipFile = await this.zip.createZip([\n {\n fileName: `${this.fileNames.manifest}`,\n blob: new Blob([JSON.stringify(manifest)])\n },\n {\n fileName: `${this.fileNames.contents}`,\n blob: new Blob([JSON.stringify(content)])\n }\n ]);\n const { data: app } = await this.appService.create(manifest);\n const { data: appBinary } = await this.appService\n .binary(app)\n .upload(zipFile, `empty-${name}.zip`);\n await this.appService.update({ id: app.id, activeVersionId: appBinary.id as string });\n return [];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -202,7 +202,8 @@ class IconCellRendererComponent {
202
202
  }
203
203
  }
204
204
  getComputedValue(property, context) {
205
- return from(this.computedPropertyService.getByName(property.name)).pipe(switchMap(definition => {
205
+ const propertyName = property.computedConfig?.__propertyName || property.name;
206
+ return from(this.computedPropertyService.getByName(propertyName)).pipe(switchMap(definition => {
206
207
  let value = '-';
207
208
  runInInjectionContext(definition.injector, () => {
208
209
  if (property.computedConfig?.dp?.length > 0) {
@@ -882,16 +883,20 @@ class AssetTableService {
882
883
  if (idx === -1)
883
884
  continue;
884
885
  const type = this.getColumnType(selectedProperties[idx]);
885
- if (type !== 'computed' && type !== 'alarm') {
886
+ // extract to a helper
887
+ if (this.checkIfColumnIsLinkable(type)) {
886
888
  return idx;
887
889
  }
888
890
  }
889
891
  }
890
892
  return selectedProperties.findIndex(prop => {
891
893
  const type = this.getColumnType(prop);
892
- return type !== 'computed' && type !== 'alarm';
894
+ return this.checkIfColumnIsLinkable(type);
893
895
  });
894
896
  }
897
+ checkIfColumnIsLinkable(type) {
898
+ return type !== 'computed' && type !== 'alarm' && type !== 'date' && type !== 'icon';
899
+ }
895
900
  getColumnType(prop) {
896
901
  return prop.columnType
897
902
  ? prop.columnType
@@ -942,7 +947,7 @@ class AssetTableService {
942
947
  path: prop.keyPath || prop.name,
943
948
  header: prop.columnLabel || prop.label || prop.title,
944
949
  iconConfig: prop.iconConfig || {},
945
- computedConfig: prop.computed ? prop.config || {} : null,
950
+ computedConfig: prop.computed && prop.config ? prop.config : null,
946
951
  showIconAndValue: config?.showIconAndValue,
947
952
  visible: prop.visible ?? true
948
953
  });
@@ -1821,17 +1826,19 @@ class AssetTableGridSettingsComponent {
1821
1826
  }
1822
1827
  applyFilter(column, dropdown) {
1823
1828
  const formGroup = column.filteringConfig?.formGroup;
1824
- this.existingColumnFilter[column.name] = formGroup?.value;
1829
+ const newFilter = { ...this.existingColumnFilter, [column.name]: formGroup?.value };
1830
+ this.existingColumnFilter = newFilter;
1825
1831
  column.filteringConfig.model = formGroup?.value;
1826
- // Update the model so Formly renders it next time
1827
- // Update config and local copy
1828
- this.widgetConfigService.updateConfig({ filterPredicate: this.existingColumnFilter });
1832
+ this.widgetConfigService.updateConfig({ filterPredicate: newFilter });
1829
1833
  dropdown.hide();
1830
1834
  }
1831
1835
  resetFilter(column, dropdown) {
1832
- delete this.existingColumnFilter[column.name];
1836
+ const newFilter = { ...this.existingColumnFilter };
1837
+ delete newFilter[column.name];
1838
+ this.existingColumnFilter = newFilter;
1833
1839
  column.filteringConfig.formGroup.reset();
1834
- this.widgetConfigService.updateConfig({ filterPredicate: this.existingColumnFilter });
1840
+ column.filteringConfig.model = {};
1841
+ this.widgetConfigService.updateConfig({ filterPredicate: newFilter });
1835
1842
  dropdown.hide();
1836
1843
  }
1837
1844
  isColumnFiltered(column) {