@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
174 lines (173 loc) • 8.45 kB
JavaScript
import { AdaptableModuleBase } from './AdaptableModuleBase';
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
import { TEAMSHARING_GET, TEAMSHARING_IMPORT_ITEM, TEAMSHARING_LINK_ITEM, TEAMSHARING_PROCESS_IMPORT, TEAMSHARING_REMOVE_ITEM, TEAMSHARING_SET, TEAMSHARING_SHARE, TEAMSHARING_UPDATE_ITEM, TeamSharingUpdateItem, } from '../Redux/ActionsReducers/TeamSharingRedux';
import * as TeamSharingRedux from '../Redux/ActionsReducers/TeamSharingRedux';
import isEqual from 'lodash/isEqual';
import { LAYOUT_SAVE } from '../Redux/ActionsReducers/LayoutRedux';
import { getSharedEntityStaleDepsItemView, SharedEntityTypeItemView, getSharedEntityActiveStatusObjectView, } from '../View/TeamSharing/SharedEntityObjectView';
import { TeamSharingApplyButton } from '../View/TeamSharing/TeamSharingApplyButton';
import { SharedEntityDependencies } from '../View/TeamSharing/SharedEntityDependencies';
import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
import flatten from 'lodash/flatten';
import AdaptableHelper from '../Utilities/Helpers/AdaptableHelper';
export class TeamSharingModule extends AdaptableModuleBase {
constructor(api) {
super(ModuleConstants.TeamSharingModuleId, ModuleConstants.TeamSharingFriendlyName, 'folder-shared', 'TeamSharingPopup', 'Team Sharing allows users to share - at run-time - Adaptable Objects between colleagues.', api);
this.SKIP_TEAMSHARING_UPDATE_ACTIONS = [
TEAMSHARING_GET,
TEAMSHARING_SET,
TEAMSHARING_SHARE,
TEAMSHARING_IMPORT_ITEM,
TEAMSHARING_PROCESS_IMPORT,
TEAMSHARING_REMOVE_ITEM,
TEAMSHARING_LINK_ITEM,
TEAMSHARING_UPDATE_ITEM,
];
}
onAdaptableReady() {
// make sure there is no zombie import process remaining (in case a previous import crashed)
this.api.internalApi.dispatchReduxAction(TeamSharingRedux.TeamSharingCommitImport());
if (this.api.teamSharingApi.isTeamSharingAvailable()) {
this.api.teamSharingApi.refreshTeamSharing();
}
this.api.eventApi.on('AdaptableStateChanged', (adaptableStateChangedInfo) => this.handleStateChanged(adaptableStateChangedInfo));
}
isModuleAvailable() {
return super.isModuleAvailable() && this.api.teamSharingApi.isTeamSharingAvailable();
}
isModuleObjectsShareable() {
return false;
}
getPopupMaxWidth() {
return 1000;
}
handleStateChanged(adaptableStateChangedInfo) {
// check if TeamSharing is activated
if (!this.api.teamSharingApi.isTeamSharingAvailable()) {
return;
}
// skip all teamsharing actions, otherwise we could get in an infinite loop
if (this.SKIP_TEAMSHARING_UPDATE_ACTIONS.includes(adaptableStateChangedInfo.action.type)) {
return;
}
// check if there is any changed adaptable object
const changedAdaptableObject = this.extractAdaptableObjectFromAction(adaptableStateChangedInfo.action);
if (!changedAdaptableObject) {
return;
}
// check if the changed adaptable object is active in TeamSharing
const activeSharedEntity = this.api.internalApi.getState().TeamSharing.ActiveSharedEntityMap[changedAdaptableObject.Uuid];
if (!activeSharedEntity) {
return;
}
// handle special case of LAYOUT_SAVE which might be called redundantly without actually changing the state
const isLayoutStateUnchanged = adaptableStateChangedInfo.action.type === LAYOUT_SAVE &&
isEqual(adaptableStateChangedInfo.oldState.Layout, adaptableStateChangedInfo.newState.Layout);
if (isLayoutStateUnchanged) {
return;
}
this.api.internalApi.dispatchReduxAction(TeamSharingUpdateItem(changedAdaptableObject, adaptableStateChangedInfo.userName));
}
extractAdaptableObjectFromAction(action) {
// this implementation is based on the assumption that any action which mutates an AdaptableObject has
// at most one(1) property which has an 'Uuid:TypeUuid' defined (and that is the AdaptableObject, of course)
if (!action) {
return;
}
return Object.values(action).find((actionPropertyValue) => AdaptableHelper.isAdaptableObject(actionPropertyValue));
}
isAdaptableObjectPresentInLocalState(sharedEntity) {
return !!this.api.internalApi
.getModuleService()
.getModuleById(sharedEntity.Module)
?.getModuleAdaptableObjects()
.find((adaptableObject) => adaptableObject.Uuid === sharedEntity.Entity.Uuid);
}
isSharedEntityADependency(sharedEntity) {
const allSharedEntries = this.api.teamSharingApi.getLoadedAdaptableSharedEntities();
return allSharedEntries.some((sharedEntryCandidate) => {
return sharedEntryCandidate?.EntityDependencyIds?.includes(sharedEntity.Uuid);
});
}
isStaleAndActive(sharedEntity) {
const staleActiveEntities = this.api.internalApi
.getTeamSharingService()
.getStaleActiveSharedEntities();
return (this.isAdaptableObjectPresentInLocalState(sharedEntity) &&
!!staleActiveEntities[sharedEntity.Uuid]);
}
getDependencies(sharedEntity) {
if (!Array.isArray(sharedEntity.EntityDependencyIds) ||
sharedEntity.EntityDependencyIds.length === 0) {
return [sharedEntity];
}
const allSharedEntities = this.api.teamSharingApi.getLoadedAdaptableSharedEntities();
const dependencies = sharedEntity.EntityDependencyIds.map((dependencyUuid) => allSharedEntities.find((entity) => entity.Uuid === dependencyUuid));
return flatten(dependencies.map((dependency) => this.getDependencies(dependency)));
}
getStaleDependencies(sharedEntity) {
return this.getDependencies(sharedEntity).filter((dependency) => dependency.Uuid !== sharedEntity.Uuid && this.isStaleAndActive(dependency));
}
toView(sharedEntity) {
const isDependency = this.isSharedEntityADependency(sharedEntity);
const staleDependencies = this.getStaleDependencies(sharedEntity);
const staleDependenciesViewItems = [];
if (staleDependencies?.length) {
staleDependenciesViewItems.push({
name: 'Stale Deps',
view: getSharedEntityStaleDepsItemView(staleDependencies),
});
}
const sharedViewItems = [];
const isStaleAndActive = this.isStaleAndActive(sharedEntity);
if (!isDependency || isStaleAndActive) {
sharedViewItems.push({
name: 'Shared',
view: getSharedEntityActiveStatusObjectView(isDependency),
});
}
return {
items: [
!isDependency &&
sharedEntity.Description && {
name: 'Name',
values: [sharedEntity.Description],
},
!isDependency && {
name: 'Share Mode',
values: [sharedEntity.Type],
},
...sharedViewItems,
{
name: 'Type',
view: SharedEntityTypeItemView,
},
...staleDependenciesViewItems,
ArrayExtensions.IsNotNullOrEmpty(sharedEntity.EntityDependencyIds) && {
name: 'Dependencies',
isLabelInline: true,
view: SharedEntityDependencies,
},
].filter(Boolean),
abObject: sharedEntity,
};
}
toViewAll() {
return ((this.api.teamSharingApi.getLoadedAdaptableSharedEntities() ?? [])
// only top level
.filter((sharedEntity) => !this.isSharedEntityADependency(sharedEntity))
.map((item) => this.toView(item)));
}
getViewProperties() {
return {
actions: [TeamSharingApplyButton],
onMount: () => {
this.api.teamSharingApi.refreshTeamSharing();
},
getDeleteAction: (sharedEntity) => {
return TeamSharingRedux.TeamSharingRemoveItem(sharedEntity.Uuid);
},
emptyView: 'Shared Items will appear here when available.',
};
}
}