forked from Ivasoft/mattermost-mobile
178 lines
4.8 KiB
TypeScript
178 lines
4.8 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
import {AppBindingLocations, AppCallResponseTypes} from '@constants/apps';
|
|
|
|
export function appsEnabled(config: Partial<ClientConfig>) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
const enabled = config['FeatureFlagAppsEnabled' as keyof Partial<ClientConfig>];
|
|
return enabled === 'true';
|
|
}
|
|
|
|
export function copyAndFillBindings(binding?: AppBinding): AppBinding | undefined {
|
|
if (!binding) {
|
|
return undefined;
|
|
}
|
|
|
|
const copy = JSON.parse(JSON.stringify(binding));
|
|
fillAndTrimBindingsInformation(copy);
|
|
return copy;
|
|
}
|
|
|
|
// fillAndTrimBindingsInformation does:
|
|
// - Build the location (e.g. channel_header/binding)
|
|
// - Inherit app calls
|
|
// - Inherit app ids
|
|
// - Trim invalid bindings (do not have an app call or app id at the leaf)
|
|
export function fillAndTrimBindingsInformation(binding?: AppBinding) {
|
|
if (!binding) {
|
|
return;
|
|
}
|
|
|
|
binding.bindings?.forEach((b) => {
|
|
// Propagate id down if not defined
|
|
if (!b.app_id) {
|
|
b.app_id = binding.app_id;
|
|
}
|
|
|
|
// Compose location
|
|
b.location = binding.location + '/' + b.location;
|
|
|
|
// Propagate call down if not defined
|
|
if (!b.call) {
|
|
b.call = binding.call;
|
|
}
|
|
|
|
fillAndTrimBindingsInformation(b);
|
|
});
|
|
|
|
// Trim branches without app_id
|
|
if (!binding.app_id) {
|
|
binding.bindings = binding.bindings?.filter((v) => v.app_id);
|
|
}
|
|
|
|
// Trim branches without calls
|
|
if (!binding.call) {
|
|
binding.bindings = binding.bindings?.filter((v) => v.call);
|
|
}
|
|
|
|
// Pull up app_id if needed
|
|
if (binding.bindings?.length && !binding.app_id) {
|
|
binding.app_id = binding.bindings[0].app_id;
|
|
}
|
|
|
|
// Pull up call if needed
|
|
if (binding.bindings?.length && !binding.call) {
|
|
binding.call = binding.bindings[0].call;
|
|
}
|
|
}
|
|
|
|
export function validateBindings(binding?: AppBinding) {
|
|
filterInvalidChannelHeaderBindings(binding);
|
|
filterInvalidCommands(binding);
|
|
filterInvalidPostMenuBindings(binding);
|
|
binding?.bindings?.forEach(fillAndTrimBindingsInformation);
|
|
}
|
|
|
|
// filterInvalidCommands remove commands without a label
|
|
function filterInvalidCommands(binding?: AppBinding) {
|
|
if (!binding) {
|
|
return;
|
|
}
|
|
|
|
const isValidCommand = (b: AppBinding): boolean => {
|
|
return Boolean(b.label);
|
|
};
|
|
|
|
const validateCommand = (b: AppBinding) => {
|
|
b.bindings = b.bindings?.filter(isValidCommand);
|
|
b.bindings?.forEach(validateCommand);
|
|
};
|
|
|
|
binding.bindings?.filter((b) => b.location === AppBindingLocations.COMMAND).forEach(validateCommand);
|
|
}
|
|
|
|
// filterInvalidChannelHeaderBindings remove bindings
|
|
// without a label.
|
|
function filterInvalidChannelHeaderBindings(binding?: AppBinding) {
|
|
if (!binding) {
|
|
return;
|
|
}
|
|
|
|
const isValidChannelHeaderBindings = (b: AppBinding): boolean => {
|
|
return Boolean(b.label);
|
|
};
|
|
|
|
const validateChannelHeaderBinding = (b: AppBinding) => {
|
|
b.bindings = b.bindings?.filter(isValidChannelHeaderBindings);
|
|
b.bindings?.forEach(validateChannelHeaderBinding);
|
|
};
|
|
|
|
binding.bindings?.filter((b) => b.location === AppBindingLocations.CHANNEL_HEADER_ICON).forEach(validateChannelHeaderBinding);
|
|
}
|
|
|
|
// filterInvalidPostMenuBindings remove bindings
|
|
// without a label.
|
|
function filterInvalidPostMenuBindings(binding?: AppBinding) {
|
|
if (!binding) {
|
|
return;
|
|
}
|
|
|
|
const isValidPostMenuBinding = (b: AppBinding): boolean => {
|
|
return Boolean(b.label);
|
|
};
|
|
|
|
const validatePostMenuBinding = (b: AppBinding) => {
|
|
b.bindings = b.bindings?.filter(isValidPostMenuBinding);
|
|
b.bindings?.forEach(validatePostMenuBinding);
|
|
};
|
|
|
|
binding.bindings?.filter((b) => b.location === AppBindingLocations.POST_MENU_ITEM).forEach(validatePostMenuBinding);
|
|
}
|
|
|
|
export function createCallContext(
|
|
appID: string,
|
|
location?: string,
|
|
channelID?: string,
|
|
teamID?: string,
|
|
postID?: string,
|
|
rootID?: string,
|
|
): AppContext {
|
|
return {
|
|
app_id: appID,
|
|
location,
|
|
channel_id: channelID,
|
|
team_id: teamID,
|
|
post_id: postID,
|
|
root_id: rootID,
|
|
};
|
|
}
|
|
|
|
export function createCallRequest(
|
|
call: AppCall,
|
|
context: AppContext,
|
|
defaultExpand: AppExpand = {},
|
|
values?: AppCallValues,
|
|
rawCommand?: string,
|
|
query?: string,
|
|
selectedField?: string,
|
|
): AppCallRequest {
|
|
return {
|
|
...call,
|
|
context,
|
|
values,
|
|
expand: {
|
|
...defaultExpand,
|
|
...call.expand,
|
|
},
|
|
raw_command: rawCommand,
|
|
query,
|
|
selected_field: selectedField,
|
|
};
|
|
}
|
|
|
|
export const makeCallErrorResponse = (errMessage: string) => {
|
|
return {
|
|
type: AppCallResponseTypes.ERROR,
|
|
error: errMessage,
|
|
};
|
|
};
|