mirror of https://github.com/rancher/dashboard.git
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import pAndNFiltering from '@shell/plugins/steve/projectAndNamespaceFiltering.utils';
|
|
|
|
type TypeIsCached = { [type: string]: boolean }
|
|
|
|
/**
|
|
* There are scenarios where we can't subscribe to subsets of a resource type
|
|
* - Multiple namespaces or projects
|
|
* - Result of Pagination (a single page of resources that have been sorted / filtered)
|
|
*
|
|
* For those scenarios we subscribe to allll changes BUT ignore changes that are not applicable to that subset
|
|
*/
|
|
class AcceptOrRejectSocketMessage {
|
|
typeIsNamespaced({ getters }: any, type: string): boolean {
|
|
return getters.haveNamespace(type)?.length > 0;
|
|
}
|
|
|
|
typeIsPaginated({ getters }: any, type: string): boolean {
|
|
return !!getters.havePage(type);
|
|
}
|
|
|
|
filteredNamespaces({ rootGetters }: any) {
|
|
// Note - activeNamespaceCache should be accurate for both namespace/project filtering and pagination namespace/project filtering
|
|
return rootGetters.activeNamespaceCache;
|
|
}
|
|
|
|
/**
|
|
* Note - namespace can be a list of projects or namespaces
|
|
*/
|
|
subscribeNamespace(namespace: string[]) {
|
|
if (pAndNFiltering.isApplicable({ namespaced: namespace, type: 'n/a' }) && namespace.length) {
|
|
return undefined; // AKA sub to everything
|
|
}
|
|
|
|
return namespace;
|
|
}
|
|
|
|
validChange({ getters, rootGetters }: any, type: string, data: any) {
|
|
// If the resource is in namespace outside of the one's we have selected in the header... ignore the change
|
|
if (this.typeIsNamespaced({ getters }, type)) {
|
|
const namespaces = this.filteredNamespaces({ rootGetters });
|
|
|
|
if (!namespaces[data.metadata.namespace]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If the resource does not meet the previously fetched paginated resource... ignore the change
|
|
if (this.typeIsPaginated({ getters }, type)) {
|
|
const page = getters['all'](type);
|
|
|
|
return !!page.find((pR: any) => pR.id === data.id);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
validateBatchChange({ getters, rootGetters }: any, batch: { [key: string]: any}) {
|
|
const namespaces = this.filteredNamespaces({ rootGetters });
|
|
|
|
const typeIs: { namespaced: TypeIsCached, paginated: TypeIsCached} = {
|
|
namespaced: {},
|
|
paginated: {},
|
|
};
|
|
|
|
Object.entries(batch).forEach(([type, entries]) => {
|
|
if (typeIs.namespaced[type] === undefined) {
|
|
typeIs.namespaced[type] = this.typeIsNamespaced({ getters }, type);
|
|
}
|
|
if (typeIs.namespaced[type]) {
|
|
const schema = getters.schemaFor(type);
|
|
|
|
if (!schema?.attributes?.namespaced) {
|
|
return;
|
|
}
|
|
|
|
Object.keys(entries).forEach((id) => {
|
|
const namespace = id.split('/')[0];
|
|
|
|
if (!namespace || !namespaces[namespace]) {
|
|
delete entries[id];
|
|
}
|
|
});
|
|
}
|
|
|
|
if (typeIs.paginated[type] === undefined) {
|
|
typeIs.paginated[type] = this.typeIsPaginated({ getters }, type);
|
|
}
|
|
if (typeIs.paginated[type]) {
|
|
const page = getters['all'](type);
|
|
|
|
Object.keys(entries).forEach((id) => {
|
|
if (!page.find((pR: any) => pR.id === id)) {
|
|
delete entries[id];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
return batch;
|
|
}
|
|
}
|
|
|
|
export default new AcceptOrRejectSocketMessage();
|