mirror of https://github.com/zulip/zulip.git
custom_profile_fields: Support non editable profile fields.
This commit allows configuration of "editable_by_user" property from the organization settings modal. It also adds support for non-editable fields in profile settings modal. Fixes #22883. Co-Authored-By: Ujjawal Modi <umodi2003@gmail.com>
This commit is contained in:
parent
fc5cdd9e83
commit
23efb5cec7
|
@ -98,6 +98,26 @@ it out.
|
|||
|
||||
{end_tabs}
|
||||
|
||||
## Configure whether users can edit custom profile fields
|
||||
|
||||
{!admin-only.md!}
|
||||
|
||||
You can configure whether users in your organization can modify their
|
||||
own custom profile fields. For example, you may want to restrict editing
|
||||
if syncing profile fields from an employee directory.
|
||||
|
||||
{start_tabs}
|
||||
|
||||
{settings_tab|profile-field-settings}
|
||||
|
||||
1. In the **Actions** column, click the **pencil** (<i class="fa fa-pencil"></i>)
|
||||
icon for the profile field you want to configure.
|
||||
|
||||
1. Toggle **Users can edit this field**.
|
||||
|
||||
4. Click **Save changes**.
|
||||
|
||||
{end_tabs}
|
||||
|
||||
## Profile field types
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {$t} from "./i18n";
|
|||
import * as people from "./people";
|
||||
import * as pill_typeahead from "./pill_typeahead";
|
||||
import * as settings_components from "./settings_components";
|
||||
import {realm} from "./state_data";
|
||||
import {current_user, realm} from "./state_data";
|
||||
import * as typeahead_helper from "./typeahead_helper";
|
||||
import type {UserPillWidget} from "./user_pill";
|
||||
import * as user_pill from "./user_pill";
|
||||
|
@ -38,6 +38,7 @@ export function append_custom_profile_fields(element_id: string, user_id: number
|
|||
|
||||
for (const field of all_custom_fields) {
|
||||
let field_value = people.get_custom_profile_data(user_id, field.id);
|
||||
const editable_by_user = current_user.is_admin || field.editable_by_user;
|
||||
const is_select_field = field.type === all_field_types.SELECT.id;
|
||||
const field_choices = [];
|
||||
|
||||
|
@ -70,6 +71,7 @@ export function append_custom_profile_fields(element_id: string, user_id: number
|
|||
field_choices,
|
||||
for_manage_user_modal: element_id === "#edit-user-form .custom-profile-field-form",
|
||||
is_empty_required_field: field.required && !field_value.value,
|
||||
editable_by_user,
|
||||
});
|
||||
$(element_id).append($(html));
|
||||
}
|
||||
|
|
|
@ -242,6 +242,7 @@ function open_custom_profile_field_form_modal(): void {
|
|||
":checked",
|
||||
),
|
||||
required: $("#profile-field-required").is(":checked"),
|
||||
editable_by_user: $("#profile_field_editable_by_user").is(":checked"),
|
||||
};
|
||||
const url = "/json/realm/profile_fields";
|
||||
const opts = {
|
||||
|
@ -461,6 +462,7 @@ function open_edit_form_modal(this: HTMLElement): void {
|
|||
choices,
|
||||
display_in_profile_summary: field.display_in_profile_summary === true,
|
||||
required: field.required,
|
||||
editable_by_user: field.editable_by_user,
|
||||
is_select_field: field.type === field_types.SELECT.id,
|
||||
is_external_account_field: field.type === field_types.EXTERNAL_ACCOUNT.id,
|
||||
valid_to_display_in_summary: is_valid_to_display_in_summary(field.type),
|
||||
|
|
|
@ -34,6 +34,7 @@ export type NarrowTerm = z.output<typeof narrow_term_schema>;
|
|||
|
||||
export const custom_profile_field_schema = z.object({
|
||||
display_in_profile_summary: z.optional(z.boolean()),
|
||||
editable_by_user: z.boolean(),
|
||||
field_data: z.string(),
|
||||
hint: z.string(),
|
||||
id: z.number(),
|
||||
|
|
|
@ -762,6 +762,18 @@ export function initialize(): void {
|
|||
},
|
||||
});
|
||||
|
||||
tippy.delegate("body", {
|
||||
target: ".settings-profile-user-field.not-editable-by-user-input-wrapper",
|
||||
content: $t({
|
||||
defaultMessage:
|
||||
"You are not allowed to change this field. Contact an administrator to update it.",
|
||||
}),
|
||||
appendTo: () => document.body,
|
||||
onHidden(instance) {
|
||||
instance.destroy();
|
||||
},
|
||||
});
|
||||
|
||||
tippy.delegate("body", {
|
||||
target: ".popover-contains-shift-hotkey",
|
||||
trigger: "mouseenter",
|
||||
|
|
|
@ -409,6 +409,10 @@
|
|||
.pill-container {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
|
||||
&.not-editable-by-user {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-profile-user-field {
|
||||
|
|
|
@ -164,6 +164,19 @@
|
|||
perspective: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
&.not-editable-by-user {
|
||||
cursor: not-allowed;
|
||||
background-color: hsl(0deg 0% 93%);
|
||||
|
||||
.pill {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.exit {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#compose-direct-recipient .pill-container {
|
||||
|
|
|
@ -1545,6 +1545,10 @@ $option_title_width: 180px;
|
|||
.datepicker {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
& input[disabled].datepicker {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
#show_my_user_profile_modal {
|
||||
|
@ -1988,6 +1992,11 @@ $option_title_width: 180px;
|
|||
cursor: default;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Needed for settings_checkbox partial. */
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
#admin_users_table .deactivated_user,
|
||||
|
|
|
@ -50,5 +50,11 @@
|
|||
{{t 'Required field' }}
|
||||
</label>
|
||||
</div>
|
||||
{{> settings_checkbox
|
||||
prefix="profile_field_"
|
||||
setting_name="editable_by_user"
|
||||
is_checked=true
|
||||
label=(t "Users can edit this field")
|
||||
}}
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -5,30 +5,30 @@
|
|||
</span>
|
||||
<div class="alert-notification custom-field-status"></div>
|
||||
<div class="settings-profile-user-field-hint">{{ field.hint }}</div>
|
||||
<div class="settings-profile-user-field {{#if is_empty_required_field}}empty-required-field{{/if}}">
|
||||
<div class="settings-profile-user-field {{#if is_empty_required_field}}empty-required-field{{/if}} {{#unless editable_by_user}}not-editable-by-user-input-wrapper{{/unless}}">
|
||||
{{#if is_long_text_field}}
|
||||
<textarea maxlength="500" class="custom_user_field_value settings_textarea" name="{{ field.id }}">{{ field_value.value }}</textarea>
|
||||
<textarea maxlength="500" class="custom_user_field_value settings_textarea" name="{{ field.id }}" {{#unless editable_by_user}}disabled{{/unless}}>{{ field_value.value }}</textarea>
|
||||
{{else if is_select_field}}
|
||||
<select class="custom_user_field_value {{#if for_manage_user_modal}}modal_select{{else}}settings_select{{/if}} bootstrap-focus-style" name="{{ field.id }}">
|
||||
<select class="custom_user_field_value {{#if for_manage_user_modal}}modal_select{{else}}settings_select{{/if}} bootstrap-focus-style" name="{{ field.id }}" {{#unless editable_by_user}}disabled{{/unless}}>
|
||||
<option value=""></option>
|
||||
{{#each field_choices}}
|
||||
<option value="{{ this.value }}" {{#if this.selected}}selected{{/if}}>{{ this.text }}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
{{else if is_user_field }}
|
||||
<div class="pill-container person_picker" name="{{ field.id }}">
|
||||
<div class="input" contenteditable="true"></div>
|
||||
<div class="pill-container person_picker {{#unless editable_by_user}}not-editable-by-user disabled{{/unless}}" name="{{ field.id }}">
|
||||
<div class="input" {{#if editable_by_user}}contenteditable="true"{{/if}}></div>
|
||||
</div>
|
||||
{{else if is_date_field }}
|
||||
<input class="custom_user_field_value datepicker {{#if for_manage_user_modal}}modal_text_input{{else}}settings_text_input{{/if}}" name="{{ field.id }}" data-field-id="{{ field.id }}" type="text"
|
||||
value="{{ field_value.value }}" />
|
||||
<span class="remove_date"><i class="fa fa-close"></i></span>
|
||||
value="{{ field_value.value }}" {{#unless editable_by_user}}disabled{{/unless}}/>
|
||||
{{#if editable_by_user}}<span class="remove_date"><i class="fa fa-close"></i></span>{{/if}}
|
||||
{{else if is_url_field }}
|
||||
<input class="custom_user_field_value {{#if for_manage_user_modal}}modal_url_input{{else}}settings_url_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="2048" />
|
||||
<input class="custom_user_field_value {{#if for_manage_user_modal}}modal_url_input{{else}}settings_url_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="2048" {{#unless editable_by_user}}disabled{{/unless}}/>
|
||||
{{else if is_pronouns_field}}
|
||||
<input class="custom_user_field_value pronouns_type_field {{#if for_manage_user_modal}}modal_text_input{{else}}settings_text_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="50" />
|
||||
<input class="custom_user_field_value pronouns_type_field {{#if for_manage_user_modal}}modal_text_input{{else}}settings_text_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="50" {{#unless editable_by_user}}disabled{{/unless}}/>
|
||||
{{else}}
|
||||
<input class="custom_user_field_value {{#if for_manage_user_modal}}modal_text_input{{else}}settings_text_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="50" />
|
||||
<input class="custom_user_field_value {{#if for_manage_user_modal}}modal_text_input{{else}}settings_text_input{{/if}}" name="{{ field.id }}" type="{{ field_type }}" value="{{ field_value.value }}" maxlength="50" {{#unless editable_by_user}}disabled{{/unless}}/>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -52,5 +52,11 @@
|
|||
{{t 'Required field' }}
|
||||
</label>
|
||||
</div>
|
||||
{{> settings_checkbox
|
||||
prefix="id-custom-profile-field-"
|
||||
setting_name="editable-by-user"
|
||||
is_checked= editable_by_user
|
||||
label=(t "Users can edit this field")
|
||||
}}
|
||||
</form>
|
||||
{{/with}}
|
||||
|
|
Loading…
Reference in New Issue