MM-62170 - CPA User Settings Profile popup (#29717)

* implement custom profile attributes for user settings and profile popover

* update PropertyField to use UserPropertyField

* updates from initial review

* misc fixes for change to IDMappedObjects

* fix: unique id

* fix: merge conflict, method ordering

* a11y fix labelledby

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
Этот коммит содержится в:
Scott Bishel
2025-01-14 08:35:55 -07:00
коммит произвёл GitHub
родитель c01f212f60
Коммит c7a87868cb
24 изменённых файлов: 701 добавлений и 14 удалений

Просмотреть файл

@@ -112,6 +112,7 @@ import type {
import type {Post, PostList, PostSearchResults, PostsUsageResponse, TeamsUsageResponse, PaginatedPostList, FilesUsageResponse, PostAcknowledgement, PostAnalytics, PostInfo} from '@mattermost/types/posts';
import type {PreferenceType} from '@mattermost/types/preferences';
import type {ProductNotices} from '@mattermost/types/product_notices';
import type {UserPropertyField, UserPropertyFieldPatch} from '@mattermost/types/properties';
import type {Reaction} from '@mattermost/types/reactions';
import type {RemoteCluster, RemoteClusterAcceptInvite, RemoteClusterPatch, RemoteClusterWithPassword} from '@mattermost/types/remote_clusters';
import type {UserReport, UserReportFilter, UserReportOptions} from '@mattermost/types/reports';
@@ -341,6 +342,18 @@ export default class Client4 {
return `${this.getRemoteClustersRoute()}/${remoteId}`;
}
getCustomProfileAttributeFieldsRoute() {
return `${this.getBaseRoute()}/custom_profile_attributes/fields`;
}
getCustomProfileAttributeFieldRoute(propertyFieldId: string) {
return `${this.getCustomProfileAttributeFieldsRoute()}/${propertyFieldId}`;
}
getCustomProfileAttributeValuesRoute() {
return `${this.getBaseRoute()}/custom_profile_attributes/values`;
}
getPostsRoute() {
return `${this.getBaseRoute()}/posts`;
}
@@ -2059,6 +2072,55 @@ export default class Client4 {
);
};
// System Properties Routes
getCustomProfileAttributeFields = async () => {
return this.doFetch<UserPropertyField[]>(
`${this.getCustomProfileAttributeFieldsRoute()}`,
{method: 'GET'},
);
};
createCustomProfileAttributeField = async (patch: UserPropertyFieldPatch) => {
return this.doFetch<UserPropertyField>(
`${this.getCustomProfileAttributeFieldsRoute()}`,
{method: 'POST', body: JSON.stringify(patch)},
);
};
patchCustomProfileAttributeField = async (fieldId: string, patch: UserPropertyFieldPatch) => {
return this.doFetch<UserPropertyField>(
`${this.getCustomProfileAttributeFieldRoute(fieldId)}`,
{method: 'PATCH', body: JSON.stringify(patch)},
);
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
deleteCustomProfileAttributeField = async (fieldId: string) => {
return this.doFetch<StatusOK>(
`${this.getCustomProfileAttributeFieldRoute(fieldId)}`,
{method: 'DELETE'},
);
};
updateCustomProfileAttributeValues = (attributeID: string, attributeValue: string) => {
const obj: { [key: string]: string } = {};
obj[attributeID] = attributeValue;
return this.doFetch<Record<string, string>>(
`${this.getCustomProfileAttributeValuesRoute()}`,
{method: 'PATCH', body: JSON.stringify(obj)},
);
};
getUserCustomProfileAttributesValues = async (userID: string) => {
const data = await this.doFetch<Record<string, string>>(
`${this.getUserRoute(userID)}/custom_profile_attributes`,
{method: 'GET'},
);
return data;
};
// Post Routes
createPost = async (post: Post) => {

Просмотреть файл

@@ -123,6 +123,7 @@ export type ClientConfig = {
FileLevel: string;
FeatureFlagAppsEnabled: string;
FeatureFlagCallsEnabled: string;
FeatureFlagCustomProfileAttributes: string;
FeatureFlagWebSocketEventScope: string;
ForgotPasswordLink: string;
GiphySdkKey: string;

Просмотреть файл

@@ -2,6 +2,8 @@
// See LICENSE.txt for license information.
import type {ClientConfig, ClientLicense} from './config';
import type {UserPropertyField} from './properties';
import type {IDMappedObjects} from './utilities';
export type GeneralState = {
config: Partial<ClientConfig>;
@@ -9,6 +11,7 @@ export type GeneralState = {
firstAdminCompleteSetup: boolean;
license: ClientLicense;
serverVersion: string;
customProfileAttributes: IDMappedObjects<UserPropertyField>;
};
export type SystemSetting = {

34
webapp/platform/types/src/properties.ts Обычный файл
Просмотреть файл

@@ -0,0 +1,34 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export type PropertyField = {
id: string;
group_id?: string;
name: string;
type: string;
attrs?: {[key: string]: unknown};
target_id?: string;
target_type?: string;
create_at: number;
update_at: number;
delete_at: number;
};
export type PropertyValue<T> = {
id: string;
target_id: string;
target_type: string;
group_id: string;
value: T;
create_at: number;
update_at: number;
delete_at: number;
}
export type UserPropertyFieldType = 'text';
export type UserPropertyFieldGroupID = 'user_properties';
export type UserPropertyField = PropertyField & {
type: UserPropertyFieldType;
}
export type UserPropertyFieldPatch = Partial<Pick<UserPropertyField, 'name' | 'attrs' | 'type'>>;