mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	settings_export: Add modal to select export_type before starting export.
This commit adds a modal which offers a way to select export_type before making a POST request to start export. Fixes part of #31201.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							478cd9220c
						
					
				
				
					commit
					6e7cb8a8c4
				
			@@ -1054,3 +1054,16 @@ export const stream_post_policy_values = {
 | 
			
		||||
        description: $t({defaultMessage: "Admins only"}),
 | 
			
		||||
    },
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
export const export_type_values = {
 | 
			
		||||
    export_public: {
 | 
			
		||||
        value: 1,
 | 
			
		||||
        description: $t({defaultMessage: "Public data"}),
 | 
			
		||||
        default: false,
 | 
			
		||||
    },
 | 
			
		||||
    export_full_with_consent: {
 | 
			
		||||
        value: 2,
 | 
			
		||||
        description: $t({defaultMessage: "Standard"}),
 | 
			
		||||
        default: true,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -3,18 +3,26 @@ import {z} from "zod";
 | 
			
		||||
 | 
			
		||||
import render_confirm_delete_data_export from "../templates/confirm_dialog/confirm_delete_data_export.hbs";
 | 
			
		||||
import render_admin_export_list from "../templates/settings/admin_export_list.hbs";
 | 
			
		||||
import render_start_export_modal from "../templates/start_export_modal.hbs";
 | 
			
		||||
 | 
			
		||||
import * as channel from "./channel";
 | 
			
		||||
import * as confirm_dialog from "./confirm_dialog";
 | 
			
		||||
import * as dialog_widget from "./dialog_widget";
 | 
			
		||||
import {$t_html} from "./i18n";
 | 
			
		||||
import {$t, $t_html} from "./i18n";
 | 
			
		||||
import * as ListWidget from "./list_widget";
 | 
			
		||||
import * as loading from "./loading";
 | 
			
		||||
import * as people from "./people";
 | 
			
		||||
import * as scroll_util from "./scroll_util";
 | 
			
		||||
import * as settings_config from "./settings_config";
 | 
			
		||||
import * as timerender from "./timerender";
 | 
			
		||||
import type {HTMLSelectOneElement} from "./types";
 | 
			
		||||
import * as ui_report from "./ui_report";
 | 
			
		||||
 | 
			
		||||
const export_consent_schema = z.object({
 | 
			
		||||
    user_id: z.number(),
 | 
			
		||||
    consented: z.boolean(),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const realm_export_schema = z.object({
 | 
			
		||||
    id: z.number(),
 | 
			
		||||
    export_time: z.number(),
 | 
			
		||||
@@ -31,6 +39,9 @@ const meta = {
 | 
			
		||||
    loaded: false,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let users_consented_for_export_count: number;
 | 
			
		||||
let total_users_count: number;
 | 
			
		||||
 | 
			
		||||
export function reset(): void {
 | 
			
		||||
    meta.loaded = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -114,27 +125,94 @@ export function populate_exports_table(exports: RealmExport[]): void {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function set_up(): void {
 | 
			
		||||
    meta.loaded = true;
 | 
			
		||||
function show_start_export_modal(): void {
 | 
			
		||||
    const html_body = render_start_export_modal({
 | 
			
		||||
        export_type_values: settings_config.export_type_values,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#export-data").on("click", (e) => {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
    function start_export(): void {
 | 
			
		||||
        dialog_widget.show_dialog_spinner();
 | 
			
		||||
        const $export_status = $("#export_status");
 | 
			
		||||
        const export_type = Number.parseInt(
 | 
			
		||||
            $<HTMLSelectOneElement>("select:not([multiple])#export_type").val()!,
 | 
			
		||||
            10,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        void channel.post({
 | 
			
		||||
            url: "/json/export/realm",
 | 
			
		||||
            data: {export_type},
 | 
			
		||||
            success() {
 | 
			
		||||
                dialog_widget.hide_dialog_spinner();
 | 
			
		||||
                ui_report.success(
 | 
			
		||||
                    $t_html({defaultMessage: "Export started. Check back in a few minutes."}),
 | 
			
		||||
                    $export_status,
 | 
			
		||||
                    4000,
 | 
			
		||||
                );
 | 
			
		||||
                dialog_widget.close();
 | 
			
		||||
            },
 | 
			
		||||
            error(xhr) {
 | 
			
		||||
                dialog_widget.hide_dialog_spinner();
 | 
			
		||||
                ui_report.error($t_html({defaultMessage: "Export failed"}), xhr, $export_status);
 | 
			
		||||
                dialog_widget.close();
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function start_export_modal_post_render(): void {
 | 
			
		||||
        $("#allow_private_data_export_stats").text(
 | 
			
		||||
            $t(
 | 
			
		||||
                {
 | 
			
		||||
                    defaultMessage:
 | 
			
		||||
                        "Exporting private data for {users_consented_for_export_count} users ({total_users_count} users total).",
 | 
			
		||||
                },
 | 
			
		||||
                {users_consented_for_export_count, total_users_count},
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
        const $export_type = $<HTMLSelectOneElement>("select:not([multiple])#export_type");
 | 
			
		||||
        $export_type.on("change", () => {
 | 
			
		||||
            const selected_export_type = Number.parseInt($export_type.val()!, 10);
 | 
			
		||||
            if (
 | 
			
		||||
                selected_export_type ===
 | 
			
		||||
                settings_config.export_type_values.export_full_with_consent.value
 | 
			
		||||
            ) {
 | 
			
		||||
                $("#allow_private_data_export_stats").show();
 | 
			
		||||
            } else {
 | 
			
		||||
                $("#allow_private_data_export_stats").hide();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dialog_widget.launch({
 | 
			
		||||
        html_heading: $t_html({defaultMessage: "Start export?"}),
 | 
			
		||||
        html_body,
 | 
			
		||||
        html_submit_button: $t_html({defaultMessage: "Start export"}),
 | 
			
		||||
        id: "start-export-modal",
 | 
			
		||||
        loading_spinner: true,
 | 
			
		||||
        on_click: start_export,
 | 
			
		||||
        post_render: start_export_modal_post_render,
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function set_up(): void {
 | 
			
		||||
    meta.loaded = true;
 | 
			
		||||
 | 
			
		||||
    void channel.get({
 | 
			
		||||
        url: "/json/export/realm/consents",
 | 
			
		||||
        success(raw_data) {
 | 
			
		||||
            const data = z
 | 
			
		||||
                .object({export_consents: z.array(export_consent_schema)})
 | 
			
		||||
                .parse(raw_data);
 | 
			
		||||
            total_users_count = data.export_consents.length;
 | 
			
		||||
            users_consented_for_export_count = data.export_consents.filter(
 | 
			
		||||
                (export_consent) => export_consent.consented,
 | 
			
		||||
            ).length;
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#start-export-button").on("click", (e) => {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
        show_start_export_modal();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Do an initial population of the table
 | 
			
		||||
 
 | 
			
		||||
@@ -3,16 +3,15 @@
 | 
			
		||||
        {{> ../help_link_widget link="/help/export-your-organization" }}
 | 
			
		||||
    </h3>
 | 
			
		||||
    <p>
 | 
			
		||||
        {{t 'Exports all users, settings, and all data visible in public channels.' }}
 | 
			
		||||
        {{t 'Any organization administrator can conduct an export.'}}
 | 
			
		||||
        {{t 'Depending on the size of your organization, an export can take anywhere from seconds to an hour.' }}
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
        {{t 'Your organization’s data will be exported in a format designed for imports into Zulip Cloud or a self-hosted installation of Zulip.' }}
 | 
			
		||||
        {{t 'You will be able to export all public data, and (optionally) private data from users who have given their permission.' }}
 | 
			
		||||
        {{#tr}}
 | 
			
		||||
            <z-link>Click here</z-link> to learn about exporting private channels and direct messages.
 | 
			
		||||
            <z-link>Learn more</z-link> about other data export options.
 | 
			
		||||
            {{#*inline "z-link"}}<a href="/help/export-your-organization" target="_blank" rel="noopener noreferrer">{{> @partial-block}}</a>{{/inline}}
 | 
			
		||||
        {{/tr}}
 | 
			
		||||
        {{t 'Note that organizations are limited to five exports per week.' }}
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
        {{t 'Depending on the size of your organization, an export can take anywhere from seconds to an hour.' }}
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    {{#if is_admin}}
 | 
			
		||||
@@ -20,8 +19,8 @@
 | 
			
		||||
        <span class="export_status_text"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
    <form>
 | 
			
		||||
        <button type="submit" class="button rounded sea-green" id="export-data">
 | 
			
		||||
            {{t 'Start export of public data' }}
 | 
			
		||||
        <button type="submit" class="button rounded sea-green" id="start-export-button">
 | 
			
		||||
            {{t 'Start export' }}
 | 
			
		||||
        </button>
 | 
			
		||||
    </form>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								web/templates/start_export_modal.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								web/templates/start_export_modal.hbs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
<p>
 | 
			
		||||
    {{#tr}}
 | 
			
		||||
        A public data export is a complete data export for your organization other than
 | 
			
		||||
        <z-private-channel-link>private channel</z-private-channel-link> messages and
 | 
			
		||||
        <z-direct-messages-link>direct messages</z-direct-messages-link>.
 | 
			
		||||
        {{#*inline "z-private-channel-link"}}<a href="/help/channel-permissions" target="_blank" rel="noopener noreferrer">{{> @partial-block}}</a>{{/inline}}
 | 
			
		||||
        {{#*inline "z-direct-messages-link"}}<a href="/help/direct-messages" target="_blank" rel="noopener noreferrer">{{> @partial-block}}</a>{{/inline}}
 | 
			
		||||
    {{/tr}}
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
    {{t 'A standard export additionally includes private data accessible to users who have allowed administrators to export their private data.' }}
 | 
			
		||||
</p>
 | 
			
		||||
<form id="start-export-form">
 | 
			
		||||
    <div class="input-group">
 | 
			
		||||
        <label for="export_type" class="modal-field-label">{{t "Export type" }}</label>
 | 
			
		||||
        <select id="export_type" class="modal_select bootstrap-focus-style">
 | 
			
		||||
            {{#each export_type_values}}
 | 
			
		||||
                <option {{#if this.default }}selected{{/if}} value="{{this.value}}">{{this.description}}</option>
 | 
			
		||||
            {{/each}}
 | 
			
		||||
        </select>
 | 
			
		||||
    </div>
 | 
			
		||||
    <p id="allow_private_data_export_stats"></p>
 | 
			
		||||
</form>
 | 
			
		||||
		Reference in New Issue
	
	Block a user