2
0
mirror of https://github.com/frappe/books.git synced 2025-02-02 20:18:26 +00:00

feat: add global setting for anonymized telemetry

This commit is contained in:
18alantom 2022-03-10 13:21:29 +05:30
parent 9bad5e69d8
commit d63e6e5cd8
6 changed files with 80 additions and 21 deletions

View File

@ -84,19 +84,11 @@ module.exports = {
default: 0, default: 0,
description: t`Hides the Get Started section from the sidebar. Change will be visible on restart or refreshing the app.`, description: t`Hides the Get Started section from the sidebar. Change will be visible on restart or refreshing the app.`,
}, },
{
fieldname: 'autoReportErrors',
label: t`Hide & Auto Report Errors`,
fieldtype: 'Check',
default: 0,
description: t`Prevent errors from showing and automatically report all errors.`,
},
], ],
quickEditFields: [ quickEditFields: [
'locale', 'locale',
'dateFormat', 'dateFormat',
'displayPrecision', 'displayPrecision',
'hideGetStarted', 'hideGetStarted',
'autoReportErrors',
], ],
}; };

View File

@ -1,6 +1,9 @@
<template> <template>
<div> <div>
<label class="flex items-center"> <label class="flex items-center">
<div class="mr-3 text-gray-900 text-sm" v-if="showLabel && !labelRight">
{{ df.label }}
</div>
<div style="width: 14px; height: 14px; overflow: hidden; cursor: pointer"> <div style="width: 14px; height: 14px; overflow: hidden; cursor: pointer">
<svg <svg
v-if="checked === 1" v-if="checked === 1"
@ -58,7 +61,7 @@
@focus="(e) => $emit('focus', e)" @focus="(e) => $emit('focus', e)"
/> />
</div> </div>
<div class="ml-3 text-gray-900 text-sm" v-if="showLabel"> <div class="ml-3 text-gray-900 text-sm" v-if="showLabel && labelRight">
{{ df.label }} {{ df.label }}
</div> </div>
</label> </label>
@ -71,6 +74,12 @@ export default {
name: 'Check', name: 'Check',
extends: Base, extends: Base,
emits: ['focus'], emits: ['focus'],
props: {
labelRight: {
default: true,
type: Boolean,
},
},
data() { data() {
return { return {
offBorderColor: 'rgba(17, 43, 66, 0.201322)', offBorderColor: 'rgba(17, 43, 66, 0.201322)',

View File

@ -8,6 +8,7 @@ export enum ConfigKeys {
LastSelectedFilePath = 'lastSelectedFilePath', LastSelectedFilePath = 'lastSelectedFilePath',
Language = 'language', Language = 'language',
DeviceId = 'deviceId', DeviceId = 'deviceId',
AnonymizedTelemetry = 'anonymizedTelemetry',
} }
export interface ConfigFile { export interface ConfigFile {

View File

@ -7,6 +7,7 @@ import {
ValidationError, ValidationError,
} from 'frappe/common/errors'; } from 'frappe/common/errors';
import BaseDocument from 'frappe/model/document'; import BaseDocument from 'frappe/model/document';
import config, { ConfigKeys } from './config';
import { IPC_ACTIONS, IPC_MESSAGES } from './messages'; import { IPC_ACTIONS, IPC_MESSAGES } from './messages';
import telemetry from './telemetry/telemetry'; import telemetry from './telemetry/telemetry';
import { showMessageDialog, showToast } from './utils'; import { showMessageDialog, showToast } from './utils';
@ -18,6 +19,10 @@ interface ErrorLog {
more?: object; more?: object;
} }
function getCanLog(): boolean {
return !!config.get(ConfigKeys.AnonymizedTelemetry);
}
function shouldNotStore(error: Error) { function shouldNotStore(error: Error) {
return [MandatoryError, ValidationError].some( return [MandatoryError, ValidationError].some(
(errorClass) => error instanceof errorClass (errorClass) => error instanceof errorClass
@ -39,14 +44,14 @@ async function reportError(errorLogObj: ErrorLog, cb?: Function) {
cb?.(); cb?.();
} }
function getToastProps(errorLogObj: ErrorLog, cb?: Function) { function getToastProps(errorLogObj: ErrorLog, canLog: boolean, cb?: Function) {
const props = { const props = {
message: t`Error: ` + errorLogObj.name, message: t`Error: ` + errorLogObj.name,
type: 'error', type: 'error',
}; };
// @ts-ignore // @ts-ignore
if (!frappe.SystemSettings?.autoReportErrors) { if (!canLog) {
Object.assign(props, { Object.assign(props, {
actionText: t`Report Error`, actionText: t`Report Error`,
action: () => { action: () => {
@ -87,10 +92,11 @@ export function handleError(
const errorLogObj = getErrorLogObject(error, more); const errorLogObj = getErrorLogObject(error, more);
// @ts-ignore // @ts-ignore
if (frappe.SystemSettings?.autoReportErrors) { const canLog = getCanLog();
if (canLog) {
reportError(errorLogObj, cb); reportError(errorLogObj, cb);
} else { } else {
showToast(getToastProps(errorLogObj, cb)); showToast(getToastProps(errorLogObj, canLog, cb));
} }
} }

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div class="flex flex-col justify-between h-full">
<TwoColumnForm <TwoColumnForm
v-if="doc" v-if="doc"
:doc="doc" :doc="doc"
@ -8,10 +8,27 @@
:emit-change="true" :emit-change="true"
@change="forwardChangeEvent" @change="forwardChangeEvent"
/> />
<div class="flex flex-row justify-between my-4"> <div class="flex flex-row justify-between items-center w-full">
<LanguageSelector class="text-sm" input-class="px-4 py-1.5"/> <div class="flex items-center rounded-lg">
<FormControl
:df="anonymizedTelemetryDf"
:showLabel="true"
:value="anonymizedTelemetry"
@change="setAnonymizedTelemetry"
class="border-r pr-4"
:label-right="false"
/>
<LanguageSelector class="text-sm w-28" input-class="px-4 py-1.5" />
</div>
<button <button
class="text-gray-900 text-sm hover:bg-gray-200 rounded-md px-4 py-1.5" class="
text-gray-900 text-sm
bg-gray-100
hover:bg-gray-200
rounded-md
px-4
py-1.5
"
@click="checkForUpdates(true)" @click="checkForUpdates(true)"
> >
Check for Updates Check for Updates
@ -21,14 +38,17 @@
</template> </template>
<script> <script>
import frappe from 'frappe'; import FormControl from '@/components/Controls/FormControl';
import TwoColumnForm from '@/components/TwoColumnForm';
import { checkForUpdates } from '@/utils';
import LanguageSelector from '@/components/Controls/LanguageSelector.vue'; import LanguageSelector from '@/components/Controls/LanguageSelector.vue';
import TwoColumnForm from '@/components/TwoColumnForm';
import config, { ConfigKeys } from '@/config';
import { checkForUpdates } from '@/utils';
import frappe from 'frappe';
export default { export default {
name: 'TabSystem', name: 'TabSystem',
components: { components: {
FormControl,
TwoColumnForm, TwoColumnForm,
LanguageSelector, LanguageSelector,
}, },
@ -36,13 +56,32 @@ export default {
data() { data() {
return { return {
doc: null, doc: null,
anonymizedTelemetry: 0,
}; };
}, },
watch: {
anonymizedTelemetry(newValue) {
config.set(ConfigKeys.AnonymizedTelemetry, !!newValue);
},
},
async mounted() { async mounted() {
this.doc = frappe.SystemSettings; this.doc = frappe.SystemSettings;
this.companyName = frappe.AccountingSettings.companyName; this.companyName = frappe.AccountingSettings.companyName;
this.anonymizedTelemetry = Number(
config.get(ConfigKeys.AnonymizedTelemetry)
);
}, },
computed: { computed: {
anonymizedTelemetryDf() {
return {
fieldname: 'anonymizedTelemetry',
label: this.t`Anonymized Telemetry`,
fieldtype: 'Check',
default: 0,
description: this
.t`Send anonymized usage data and error reports to help improve the product.`,
};
},
fields() { fields() {
let meta = frappe.getMeta('SystemSettings'); let meta = frappe.getMeta('SystemSettings');
return meta.getQuickEditFields(); return meta.getQuickEditFields();
@ -50,6 +89,9 @@ export default {
}, },
methods: { methods: {
checkForUpdates, checkForUpdates,
setAnonymizedTelemetry(value) {
this.anonymizedTelemetry = value;
},
forwardChangeEvent(...args) { forwardChangeEvent(...args) {
this.$emit('change', ...args); this.$emit('change', ...args);
}, },

View File

@ -1,3 +1,4 @@
import config, { ConfigKeys } from '@/config';
import frappe from 'frappe'; import frappe from 'frappe';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { getCounts, getDeviceId, getInstanceId, getLocale } from './helpers'; import { getCounts, getDeviceId, getInstanceId, getLocale } from './helpers';
@ -17,11 +18,19 @@ class TelemetryManager {
this.#started = true; this.#started = true;
} }
getCanLog() {
return !!config.get(ConfigKeys.AnonymizedTelemetry);
}
log(verb: Verb, noun: Noun, more?: Record<string, unknown>) { log(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
if (!this.#started) { if (!this.#started) {
this.start(); this.start();
} }
if (!this.getCanLog) {
return;
}
const time = new Date().valueOf(); const time = new Date().valueOf();
if (this.#telemetryObject.timeline === undefined) { if (this.#telemetryObject.timeline === undefined) {
this.#telemetryObject.timeline = []; this.#telemetryObject.timeline = [];
@ -45,7 +54,7 @@ class TelemetryManager {
//@ts-ignore //@ts-ignore
this.#telemetryObject.version = frappe.store.appVersion ?? ''; this.#telemetryObject.version = frappe.store.appVersion ?? '';
this.#telemetryObject.counts = await getCounts(); this.#telemetryObject.counts = this.getCanLog() ? await getCounts() : {};
this.#telemetryObject.closeTime = new Date().valueOf(); this.#telemetryObject.closeTime = new Date().valueOf();
} }