From 0bc114ff631c2b4be533c9a46b497e46784f7483 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sat, 2 Nov 2019 15:47:07 +0300 Subject: [PATCH 001/101] Create component for rendering setting form from description --- src/views/settings/components/Setting.vue | 86 +++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/views/settings/components/Setting.vue diff --git a/src/views/settings/components/Setting.vue b/src/views/settings/components/Setting.vue new file mode 100644 index 00000000..cbcb1cd5 --- /dev/null +++ b/src/views/settings/components/Setting.vue @@ -0,0 +1,86 @@ + + + + + From b591f58fb209fa6af83873f7b349502f94cafb65 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sat, 2 Nov 2019 15:54:04 +0300 Subject: [PATCH 002/101] Call fetch description and migrate to db --- src/api/settings.js | 18 +++++ src/store/modules/settings.js | 134 ++++++++++++++++++---------------- 2 files changed, 91 insertions(+), 61 deletions(-) diff --git a/src/api/settings.js b/src/api/settings.js index a0da39cd..55e35100 100644 --- a/src/api/settings.js +++ b/src/api/settings.js @@ -2,6 +2,15 @@ import request from '@/utils/request' import { getToken } from '@/utils/auth' import { baseName } from './utils' +export async function fetchDescription(authHost, token) { + return await request({ + baseURL: baseName(authHost), + url: `/api/pleroma/admin/config/descriptions`, + method: 'get', + headers: authHeaders(token) + }) +} + export async function fetchSettings(authHost, token) { return await request({ baseURL: baseName(authHost), @@ -11,6 +20,15 @@ export async function fetchSettings(authHost, token) { }) } +export async function migrateToDB(authHost, token) { + return await request({ + baseURL: baseName(authHost), + url: `/api/pleroma/admin/config/migrate_to_db`, + method: 'get', + headers: authHeaders(token) + }) +} + export async function updateSettings(configs, authHost, token) { return await request({ baseURL: baseName(authHost), diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index bb6bd8c1..8fd63099 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -1,54 +1,55 @@ -import { fetchSettings, updateSettings, uploadMedia } from '@/api/settings' +import { fetchDescription, fetchSettings, migrateToDB, updateSettings, uploadMedia } from '@/api/settings' import { filterIgnored, parseTuples, valueHasTuples, wrapConfig } from './normalizers' const settings = { state: { + description: [], settings: { - 'activitypub': {}, - 'adapter': {}, - 'admin_token': {}, - 'assets': { mascots: {}}, - 'auth': {}, - 'auto_linker': { opts: {}}, - 'backends': {}, - 'chat': {}, - 'console': { colors: {}}, - 'credentials': {}, - 'database': {}, - 'ecto_repos': {}, - 'email_notifications': { digest: {}}, - 'emoji': { groups: {}}, - 'enabled': {}, - 'ex_syslogger': {}, - 'expose': {}, - 'fetch_initial_posts': {}, - 'format_encoders': {}, - 'frontend_configurations': { pleroma_fe: {}, masto_fe: {}}, - 'gopher': {}, - 'hackney_pools': { federation: {}, media: {}, upload: {}}, - 'handler': {}, - 'headers': {}, - 'http': { adapter: {}}, - 'http_security': {}, - 'instance': { poll_limits: {}}, - 'level': {}, - 'ldap': {}, - 'markup': {}, - 'max_age': {}, - 'media_proxy': { proxy_opts: {}}, - 'meta': {}, - 'methods': {}, - 'mrf_hellthread': {}, - 'mrf_keyword': { replace: {}}, - 'mrf_mention': {}, - 'mrf_normalize_markup': {}, - 'mrf_rejectnonpublic': {}, - 'mrf_simple': {}, - 'mrf_subchain': { match_actor: {}}, - 'mrf_user_allowlist': {}, - 'mrf_vocabulary': {}, - 'oauth2': {}, - 'password_authenticator': {}, + ':activitypub': {}, + ':adapter': {}, + ':admin_token': {}, + ':assets': { mascots: {}}, + ':auth': {}, + ':auto_linker': { opts: {}}, + ':backends': {}, + ':chat': {}, + ':console': { colors: {}}, + ':credentials': {}, + ':database': {}, + ':ecto_repos': {}, + ':email_notifications': { digest: {}}, + ':emoji': { groups: {}}, + ':enabled': {}, + ':ex_syslogger': {}, + ':expose': {}, + ':fetch_initial_posts': {}, + ':format_encoders': {}, + ':frontend_configurations': { pleroma_fe: {}, masto_fe: {}}, + ':gopher': {}, + ':hackney_pools': { federation: {}, media: {}, upload: {}}, + ':handler': {}, + ':headers': {}, + ':http': { adapter: {}}, + ':http_security': {}, + ':instance': { poll_limits: {}}, + ':level': {}, + ':ldap': {}, + ':markup': {}, + ':max_age': {}, + ':media_proxy': { proxy_opts: {}}, + ':meta': {}, + ':methods': {}, + ':mrf_hellthread': {}, + ':mrf_keyword': { replace: {}}, + ':mrf_mention': {}, + ':mrf_normalize_markup': {}, + ':mrf_rejectnonpublic': {}, + ':mrf_simple': {}, + ':mrf_subchain': { match_actor: {}}, + ':mrf_user_allowlist': {}, + ':mrf_vocabulary': {}, + ':oauth2': {}, + ':password_authenticator': {}, 'Pleroma.Captcha': {}, 'Pleroma.Captcha.Kocaptcha': {}, 'Pleroma.Emails.Mailer': {}, @@ -67,22 +68,22 @@ const settings = { { http: false, url: {}, render_errors: {}, pubsub: {}}, 'Pleroma.Web.Federator.RetryQueue': {}, 'Pleroma.Web.Metadata': {}, - 'port': {}, - 'priv_dir': {}, - 'queues': {}, - 'rate_limit': {}, - 'rich_media': {}, - 'suggestions': {}, - 'types': { value: {}}, + ':port': {}, + ':priv_dir': {}, + ':queues': {}, + ':rate_limit': {}, + ':rich_media': {}, + ':suggestions': {}, + ':types': { value: {}}, 'Ueberauth': {}, 'Ueberauth.Strategy.Facebook.OAuth': {}, 'Ueberauth.Strategy.Google.OAuth': {}, 'Ueberauth.Strategy.Microsoft.OAuth': {}, 'Ueberauth.Strategy.Twitter.OAuth': {}, - 'user': {}, - 'uri_schemes': {}, - 'vapid_details': {}, - 'webhook_url': {} + ':user': {}, + ':uri_schemes': {}, + ':vapid_details': {}, + ':webhook_url': {} }, ignoredIfNotEnabled: ['enabled', 'handler', 'password_authenticator', 'port', 'priv_dir'], loading: true @@ -91,14 +92,16 @@ const settings = { REWRITE_CONFIG: (state, { tab, data }) => { state.settings[tab] = data }, + SET_DESCRIPTION: (state, data) => { + state.description = data + }, SET_LOADING: (state, status) => { state.loading = status }, SET_SETTINGS: (state, data) => { - const newSettings = data.reduce((acc, config) => { - const key = config.key[0] === ':' ? config.key.substr(1) : config.key - const value = valueHasTuples(key, config.value) ? { value: config.value } : parseTuples(config.value, key) - acc[key] = { ...acc[key], ...value } + const newSettings = data.reduce((acc, { key, value }) => { + const parsedValue = valueHasTuples(key, value) ? { value } : parseTuples(value, key) + acc[key] = { ...acc[key], ...parsedValue } return acc }, state.settings) state.settings = newSettings @@ -115,9 +118,18 @@ const settings = { async FetchSettings({ commit, dispatch, getters }) { commit('SET_LOADING', true) const response = await fetchSettings(getters.authHost, getters.token) + const description = await fetchDescription(getters.authHost, getters.token) + if (response.data.configs.length === 0) { + dispatch('MigrateToDB') + dispatch('FetchSettings') + } + commit('SET_DESCRIPTION', description.data) commit('SET_SETTINGS', response.data.configs) commit('SET_LOADING', false) }, + async MigrateToDB({ getters }) { + await migrateToDB(getters.authHost, getters.token) + }, RewriteConfig({ commit }, { tab, data }) { commit('REWRITE_CONFIG', { tab, data }) }, From ba1d3f1f76d2bfe0c4048658f808fa69b7aadc5a Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sat, 2 Nov 2019 15:56:30 +0300 Subject: [PATCH 003/101] Use Setting component to render ActivityPub, Authentication and Captcha --- src/views/settings/components/ActivityPub.vue | 47 +--- .../settings/components/Authentication.vue | 259 ++---------------- src/views/settings/components/Captcha.vue | 43 +-- src/views/settings/styles/main.scss | 3 + 4 files changed, 63 insertions(+), 289 deletions(-) diff --git a/src/views/settings/components/ActivityPub.vue b/src/views/settings/components/ActivityPub.vue index 903e34fe..ead3491c 100644 --- a/src/views/settings/components/ActivityPub.vue +++ b/src/views/settings/components/ActivityPub.vue @@ -1,33 +1,11 @@ + + From c388d42d404c46da8832ad7a4632a46932418a51 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Fri, 6 Dec 2019 15:50:23 +0900 Subject: [PATCH 056/101] Parse ip values and clear updated settings after submit --- src/store/modules/normalizers.js | 9 +++++---- src/store/modules/settings.js | 4 ++++ src/views/settings/components/Inputs.vue | 10 +++++----- src/views/settings/components/inputComponents/index.js | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 src/views/settings/components/inputComponents/index.js diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 81c57c89..a41c4ff5 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -27,9 +27,7 @@ export const parseTuples = (tuples, key) => { ? accum[item.tuple[0]] = parseNonAtomObject(item.tuple[1]) : accum[item.tuple[0]] = parseObject(item.tuple[1]) } else { - key === 'mrf_user_allowlist' - ? accum[item.tuple[0]] = item.tuple[1] - : accum[item.tuple[0]] = item.tuple[1] + accum[item.tuple[0]] = item.tuple[1] } return accum }, {}) @@ -79,10 +77,13 @@ export const wrapUpdatedSettings = (group, settings) => { const wrapValues = settings => { return Object.keys(settings).map(setting => { const [type, value] = settings[setting] - if (type === 'keyword') { + if (type === 'keyword' || type.includes('keyword')) { return { 'tuple': [setting, wrapValues(value)] } } else if (type === 'atom') { return { 'tuple': [setting, `:${value}`] } + } else if (setting === ':ip') { + const ip = value.split('.').map(s => parseInt(s, 10)) + return { 'tuple': [setting, { 'tuple': ip }] } } else { return { 'tuple': [setting, value] } } diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 0c42d807..6c372aed 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -24,6 +24,9 @@ const settings = { loading: true }, mutations: { + CLEAR_UPDATED_SETTINGS: (state) => { + state.updatedSettings = {} + }, REWRITE_CONFIG: (state, { tab, data }) => { state.settings[tab] = data }, @@ -77,6 +80,7 @@ const settings = { }, []) const response = await updateSettings(configs, getters.authHost, getters.token) commit('SET_SETTINGS', response.data.configs) + commit('CLEAR_UPDATED_SETTINGS') }, UpdateSettings({ commit }, { group, key, input, value, type }) { key diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 83ca7345..8ec62cab 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -56,10 +56,10 @@ lang="elixir" theme="chrome"/> + v-if="setting.key === ':ip'" + :value="inputValue" + placeholder="xxx.xxx.xxx.xx" + @input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/> Date: Fri, 6 Dec 2019 16:11:00 +0900 Subject: [PATCH 057/101] Handle groups that doesn't have key --- src/store/modules/normalizers.js | 4 +++- src/store/modules/settings.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index a41c4ff5..18d886d7 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -3,6 +3,8 @@ const nonAtomsObjects = ['match_actor', ':match_actor'] const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits', 'styling'] const objectParents = ['mascots'] +const groupWithoutKey = settings => settings.noKey ? settings.noKey[1] : false + // REFACTOR export const parseTuples = (tuples, key) => { return tuples.reduce((accum, item) => { @@ -69,7 +71,7 @@ export const valueHasTuples = (key, value) => { export const wrapUpdatedSettings = (group, settings) => { return Object.keys(settings).map((key) => { - const value = wrapValues(settings[key]) + const value = groupWithoutKey(settings[key]) || wrapValues(settings[key]) return { group, key, value } }) } diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 6c372aed..8e6e65c0 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -85,7 +85,7 @@ const settings = { UpdateSettings({ commit }, { group, key, input, value, type }) { key ? commit('UPDATE_SETTINGS', { group, key, input, value, type }) - : commit('UPDATE_SETTINGS', { group, key: input, input: 'value', value, type }) + : commit('UPDATE_SETTINGS', { group, key: input, input: 'noKey', value, type }) }, UpdateState({ commit }, { group, key, input, value }) { key From 59e9802337b612275982ed5c305e789ea4aaf69f Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Fri, 6 Dec 2019 17:30:17 +0900 Subject: [PATCH 058/101] Wrap values with type map --- src/store/modules/normalizers.js | 8 +++++++- src/store/modules/settings.js | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 18d886d7..f2aaa9b5 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -3,7 +3,7 @@ const nonAtomsObjects = ['match_actor', ':match_actor'] const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits', 'styling'] const objectParents = ['mascots'] -const groupWithoutKey = settings => settings.noKey ? settings.noKey[1] : false +const groupWithoutKey = settings => settings._value ? settings._value[1] : false // REFACTOR export const parseTuples = (tuples, key) => { @@ -83,6 +83,12 @@ const wrapValues = settings => { return { 'tuple': [setting, wrapValues(value)] } } else if (type === 'atom') { return { 'tuple': [setting, `:${value}`] } + } else if (type === 'map') { + const objectValue = Object.keys(value).reduce((acc, key) => { + acc[key] = value[key][1] + return acc + }, {}) + return { 'tuple': [setting, objectValue] } } else if (setting === ':ip') { const ip = value.split('.').map(s => parseInt(s, 10)) return { 'tuple': [setting, { 'tuple': ip }] } diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 8e6e65c0..a3216331 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -85,7 +85,7 @@ const settings = { UpdateSettings({ commit }, { group, key, input, value, type }) { key ? commit('UPDATE_SETTINGS', { group, key, input, value, type }) - : commit('UPDATE_SETTINGS', { group, key: input, input: 'noKey', value, type }) + : commit('UPDATE_SETTINGS', { group, key: input, input: '_value', value, type }) }, UpdateState({ commit }, { group, key, input, value }) { key From 7dc74ef70fdc88480f98d9c6c2e34ad22c803c75 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 9 Dec 2019 11:30:53 +0300 Subject: [PATCH 059/101] Extract mascots input into separate component --- src/store/modules/normalizers.js | 4 +- src/views/settings/components/Inputs.vue | 56 ++-------- .../inputComponents/AutoLinkerInput.vue | 1 - .../inputComponents/MascotsInput.vue | 103 ++++++++++++++++++ .../components/inputComponents/index.js | 1 + 5 files changed, 114 insertions(+), 51 deletions(-) create mode 100644 src/views/settings/components/inputComponents/MascotsInput.vue diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index f2aaa9b5..3822f96f 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -70,6 +70,7 @@ export const valueHasTuples = (key, value) => { } export const wrapUpdatedSettings = (group, settings) => { + console.log(group, settings) return Object.keys(settings).map((key) => { const value = groupWithoutKey(settings[key]) || wrapValues(settings[key]) return { group, key, value } @@ -78,7 +79,8 @@ export const wrapUpdatedSettings = (group, settings) => { const wrapValues = settings => { return Object.keys(settings).map(setting => { - const [type, value] = settings[setting] + console.log(settings[setting]) + const [type, value] = Array.isArray(settings[setting]) ? settings[setting] : ['', settings[setting]] if (type === 'keyword' || type.includes('keyword')) { return { 'tuple': [setting, wrapValues(value)] } } else if (type === 'atom') { diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 8ec62cab..16425bfc 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -148,20 +148,10 @@ class="value-input" @input="updateSetting($event, settingGroup.group, settingGroup.key, setting.key)"/> -
- -
-
-
-
- - -
- - -
- -
+ + + +
@@ -187,13 +177,14 @@ import AceEditor from 'vue2-ace-editor' import 'brace/mode/elixir' import 'default-passive-events' -import { AutoLinkerInput } from './inputComponents' +import { AutoLinkerInput, MascotsInput } from './inputComponents' export default { name: 'Inputs', components: { editor: AceEditor, - AutoLinkerInput + AutoLinkerInput, + MascotsInput }, props: { customLabelWidth: { @@ -265,11 +256,6 @@ export default { labelWidth() { return this.isMobile ? '100px' : '240px' }, - mascotsValue() { - return Object.keys(this.data) - .map(mascotName => - [mascotName, this.data[mascotName][':url'], this.data[mascotName][':mime_type']]) - }, proxyUrlData() { if (!this.data[this.setting.key]) { return null @@ -319,12 +305,6 @@ export default { }, {}) this.updateSetting({ ...updatedValue, '': [] }, this.settingGroup.group, this.settingGroup.key, this.setting.key) }, - addRowToMascots() { - const updatedValue = this.data[':mascots'].reduce((acc, el, i) => { - return { ...acc, [el[0]]: { url: el[1], mime_type: el[2] }} - }, {}) - this.updateSetting({ ...updatedValue, '': { url: '', mime_type: '' }}, this.settingGroup.group, 'assets', 'mascots') - }, deleteEditableKeywordRow(index) { const filteredValues = this.editableKeywordData(this.data).filter((el, i) => index !== i) const updatedValue = filteredValues.reduce((acc, el, i) => { @@ -334,13 +314,6 @@ export default { this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) }, deleteIcondRow(index) {}, - deleteMascotsRow(index) { - const filteredValues = this.data[':mascots'].filter((el, i) => index !== i) - const updatedValue = filteredValues.reduce((acc, el, i) => { - return { ...acc, [el[0]]: { url: el[1], mime_type: el[2] }} - }, {}) - this.updateSetting(updatedValue, this.settingGroup.group, 'assets', 'mascots') - }, editableKeywordWithInput(key) { return key === ':replace' }, @@ -367,21 +340,6 @@ export default { this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) }, parseIcons(value, inputType, index) {}, - parseMascots(value, inputType, index) { - const updatedValue = this.data[':mascots'].reduce((acc, el, i) => { - if (index === i) { - if (inputType === 'name') { - return { ...acc, [value]: { url: el[1], mime_type: el[2] }} - } else if (inputType === 'url') { - return { ...acc, [el[0]]: { url: value, mime_type: el[2] }} - } else { - return { ...acc, [el[0]]: { url: el[1], mime_type: value }} - } - } - return { ...acc, [el[0]]: { url: el[1], mime_type: el[2] }} - }, {}) - this.updateSetting(updatedValue, this.settingGroup.group, 'assets', 'mascots') - }, parseRateLimiter(value, input, typeOfInput, typeOfLimit, currentValue) { if (typeOfLimit === 'oneLimit') { const valueToSend = typeOfInput === 'scale' ? { 'tuple': [value, currentValue[1]] } : { 'tuple': [currentValue[0], value] } diff --git a/src/views/settings/components/inputComponents/AutoLinkerInput.vue b/src/views/settings/components/inputComponents/AutoLinkerInput.vue index 0a305f9b..97f7adf8 100644 --- a/src/views/settings/components/inputComponents/AutoLinkerInput.vue +++ b/src/views/settings/components/inputComponents/AutoLinkerInput.vue @@ -34,7 +34,6 @@ export default { } } }, - computed: {}, methods: { autoLinkerBooleanValue(key) { const value = this.data[this.setting.key] diff --git a/src/views/settings/components/inputComponents/MascotsInput.vue b/src/views/settings/components/inputComponents/MascotsInput.vue new file mode 100644 index 00000000..8bcc73cb --- /dev/null +++ b/src/views/settings/components/inputComponents/MascotsInput.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js index ff6dfc2b..eb2d7b83 100644 --- a/src/views/settings/components/inputComponents/index.js +++ b/src/views/settings/components/inputComponents/index.js @@ -1 +1,2 @@ export { default as AutoLinkerInput } from './AutoLinkerInput' +export { default as MascotsInput } from './MascotsInput' From 760cdd3db96bb7f12cb1447871461349c0c125dc Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Mon, 9 Dec 2019 13:17:28 +0300 Subject: [PATCH 060/101] Store generated id in mascots state --- src/store/modules/normalizers.js | 17 +++--- src/views/settings/components/Setting.vue | 2 +- .../inputComponents/MascotsInput.vue | 53 +++++++------------ 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 3822f96f..13be4fd3 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -27,7 +27,7 @@ export const parseTuples = (tuples, key) => { } else if (item.tuple[1] && typeof item.tuple[1] === 'object') { nonAtomsObjects.includes(item.tuple[0]) ? accum[item.tuple[0]] = parseNonAtomObject(item.tuple[1]) - : accum[item.tuple[0]] = parseObject(item.tuple[1]) + : accum[item.tuple[0]] = parseObject(item.tuple) } else { accum[item.tuple[0]] = item.tuple[1] } @@ -49,11 +49,16 @@ const parseNonAtomObject = (object) => { }, {}) } -const parseObject = (object) => { - return Object.keys(object).reduce((acc, item) => { - acc[item] = object[item] - return acc - }, {}) +const parseObject = tuple => { + return tuple[0] === ':mascots' + ? Object.keys(tuple[1]).reduce((acc, item) => { + acc[item] = { ...tuple[1][item], id: `f${(~~(Math.random() * 1e8)).toString(16)}` } + return acc + }, {}) + : Object.keys(tuple[1]).reduce((acc, item) => { + acc[item] = tuple[1][item] + return acc + }, {}) } export const valueHasTuples = (key, value) => { diff --git a/src/views/settings/components/Setting.vue b/src/views/settings/components/Setting.vue index f6641382..9293ec3d 100644 --- a/src/views/settings/components/Setting.vue +++ b/src/views/settings/components/Setting.vue @@ -40,7 +40,7 @@ :nested="true"/>
- +
diff --git a/src/views/settings/components/inputComponents/MascotsInput.vue b/src/views/settings/components/inputComponents/MascotsInput.vue index 8bcc73cb..727fbe64 100644 --- a/src/views/settings/components/inputComponents/MascotsInput.vue +++ b/src/views/settings/components/inputComponents/MascotsInput.vue @@ -1,17 +1,17 @@ From 37cdff3745f71b334e01db5d455fd95e0c9c7cc7 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Wed, 11 Dec 2019 00:24:43 +0300 Subject: [PATCH 063/101] Use data from state for settings that cannot be partially updated --- src/store/modules/normalizers.js | 14 ++++++++++++-- src/store/modules/settings.js | 24 ++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 7231a476..4fbfecae 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -58,6 +58,18 @@ const parseObject = object => { }, {}) } +export const partialUpdate = (group, key) => { + if ((group === ':pleroma' && key === ':ecto_repos') || + (group === ':quack' && key === ':meta') || + (group === ':mime' && key === ':types') || + (group === ':auto_linker' && key === ':opts') || + (group === ':swarm' && key === ':node_blacklist') || + (group === ':cors_plug' && [':max_age', ':methods', ':expose', ':headers'].includes(key))) { + return false + } + return true +} + export const valueHasTuples = (key, value) => { const valueIsArrayOfNonObjects = Array.isArray(value) && value.length > 0 && typeof value[0] !== 'object' return key === ':meta' || @@ -72,7 +84,6 @@ export const valueHasTuples = (key, value) => { } export const wrapUpdatedSettings = (group, settings) => { - console.log(group, settings) return Object.keys(settings).map((key) => { const value = groupWithoutKey(settings[key]) || wrapValues(settings[key]) return { group, key, value } @@ -81,7 +92,6 @@ export const wrapUpdatedSettings = (group, settings) => { const wrapValues = settings => { return Object.keys(settings).map(setting => { - console.log(settings[setting]) const [type, value] = Array.isArray(settings[setting]) ? settings[setting] : ['', settings[setting]] if (type === 'keyword' || type.includes('keyword')) { return { 'tuple': [setting, wrapValues(value)] } diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index adb2a05a..640bc237 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -1,5 +1,5 @@ import { fetchDescription, fetchSettings, updateSettings, uploadMedia } from '@/api/settings' -import { parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers' +import { parseTuples, partialUpdate, valueHasTuples, wrapUpdatedSettings } from './normalizers' const settings = { state: { @@ -56,7 +56,7 @@ const settings = { } }, actions: { - async FetchSettings({ commit, dispatch, getters }) { + async FetchSettings({ commit, getters }) { commit('SET_LOADING', true) const response = await fetchSettings(getters.authHost, getters.token) const description = await fetchDescription(getters.authHost, getters.token) @@ -69,8 +69,24 @@ const settings = { commit('REWRITE_CONFIG', { tab, data }) }, async SubmitChanges({ getters, commit, state }) { - const configs = Object.keys(state.updatedSettings).reduce((acc, group) => { - return [...acc, ...wrapUpdatedSettings(group, state.updatedSettings[group])] + const updatedData = Object.keys(state.updatedSettings).reduce((acc, group) => { + acc[group] = Object.keys(state.updatedSettings[group]).reduce((acc, key) => { + if (!partialUpdate(group, key)) { + const updated = Object.keys(state.settings[group][key]).reduce((acc, settingName) => { + acc[settingName] = ['', state.settings[group][key][settingName]] + return acc + }, {}) + acc[key] = updated + return acc + } + acc[key] = state.updatedSettings[group][key] + return acc + }, {}) + return acc + }, {}) + + const configs = Object.keys(updatedData).reduce((acc, group) => { + return [...acc, ...wrapUpdatedSettings(group, updatedData[group])] }, []) const response = await updateSettings(configs, getters.authHost, getters.token) commit('SET_SETTINGS', response.data.configs) From fc220c56352fe91b899825c0819ddd1e585bf348 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Thu, 12 Dec 2019 16:05:20 +0300 Subject: [PATCH 064/101] Fix parsing dispatch setting --- src/views/settings/components/Inputs.vue | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 16425bfc..b1624e5d 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -27,15 +27,6 @@ :value="option" :key="index"/> - { return { ...acc, [el[0]]: el[1] } }, {}) - console.log(updatedValue) this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) }, deleteIcondRow(index) {}, @@ -336,7 +323,6 @@ export default { } return { ...acc, [el[0]]: el[1] } }, {}) - console.log(updatedValue) this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) }, parseIcons(value, inputType, index) {}, @@ -377,7 +363,6 @@ export default { ) }, toggleAtomTuple(value, tab, input) { - console.log(value) }, toggleLimits(value, input) { this.updateSetting(value, this.settingGroup.group, 'rate_limit', input) From cd6ab3718b55400dfabc47ca7a9fc9fc5e5c3e0f Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Fri, 13 Dec 2019 22:11:29 +0300 Subject: [PATCH 065/101] Extract inputs for editable keyword into separate component, process groups --- src/store/modules/normalizers.js | 4 + src/views/settings/components/Inputs.vue | 75 ++---------- .../inputComponents/EditableKeyword.vue | 109 ++++++++++++++++++ .../components/inputComponents/index.js | 1 + 4 files changed, 125 insertions(+), 64 deletions(-) create mode 100644 src/views/settings/components/inputComponents/EditableKeyword.vue diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 4fbfecae..c9dbc850 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -12,6 +12,10 @@ export const parseTuples = (tuples, key) => { accum[item.tuple[0]] = item.tuple[1] } else if (key === ':mascots') { accum[item.tuple[0]] = { ...item.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` } + } else if (item.tuple[0] === ':groups') { + accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => { + return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] + }, []) } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) || // should be removed (item.tuple[0] === ':tlsopts' && item.tuple[1].length === 0)) { accum[item.tuple[0]] = {} diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index b1624e5d..024b4b7a 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -55,30 +55,6 @@ @input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"> -
-
- : - - -
- -
-
-
- : - - -
- -
-
-
- : - - -
- -
Disabled @@ -137,8 +113,9 @@ @input="updateSetting($event, settingGroup.group, settingGroup.key, setting.key)"/>
- - + + +
@@ -165,13 +142,14 @@ import AceEditor from 'vue2-ace-editor' import 'brace/mode/elixir' import 'default-passive-events' -import { AutoLinkerInput, MascotsInput } from './inputComponents' +import { AutoLinkerInput, EditableKeyword, MascotsInput } from './inputComponents' export default { name: 'Inputs', components: { editor: AceEditor, AutoLinkerInput, + EditableKeyword, MascotsInput }, props: { @@ -183,7 +161,7 @@ export default { required: false }, data: { - type: Object || Array, + type: [Object, Array], default: function() { return {} } @@ -287,43 +265,12 @@ export default { methods: { addIconToIcons() {}, addValueToIcons() {}, - addRowToEditableKeyword() { - const updatedValue = this.editableKeywordData(this.data).reduce((acc, el, i) => { - return { ...acc, [el[0]]: el[1] } - }, {}) - this.updateSetting({ ...updatedValue, '': [] }, this.settingGroup.group, this.settingGroup.key, this.setting.key) - }, - deleteEditableKeywordRow(index) { - const filteredValues = this.editableKeywordData(this.data).filter((el, i) => index !== i) - const updatedValue = filteredValues.reduce((acc, el, i) => { - return { ...acc, [el[0]]: el[1] } - }, {}) - this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) - }, deleteIcondRow(index) {}, - editableKeywordWithInput(key) { - return key === ':replace' - }, - editableKeywordWithInteger(type) { - return Array.isArray(type) - ? type.includes('keyword') && type.includes('integer') - : false - }, - editableKeywordWithSelect(type) { - return type === 'map' || - (Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) - }, - editableKeywordData(data) { - return Object.keys(data).map(key => [key, data[key]]) - }, - parseEditableKeyword(value, inputType, index) { - const updatedValue = this.editableKeywordData(this.data).reduce((acc, el, i) => { - if (index === i) { - return inputType === 'key' ? { ...acc, [value]: el[1] } : { ...acc, [el[0]]: value } - } - return { ...acc, [el[0]]: el[1] } - }, {}) - this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key) + editableKeyword(key, type) { + return key === ':replace' || + (Array.isArray(type) && type.includes('keyword') && type.includes('integer')) || + type === 'map' || + (Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) }, parseIcons(value, inputType, index) {}, parseRateLimiter(value, input, typeOfInput, typeOfLimit, currentValue) { diff --git a/src/views/settings/components/inputComponents/EditableKeyword.vue b/src/views/settings/components/inputComponents/EditableKeyword.vue new file mode 100644 index 00000000..f1f106cd --- /dev/null +++ b/src/views/settings/components/inputComponents/EditableKeyword.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js index eb2d7b83..922dea1b 100644 --- a/src/views/settings/components/inputComponents/index.js +++ b/src/views/settings/components/inputComponents/index.js @@ -1,2 +1,3 @@ export { default as AutoLinkerInput } from './AutoLinkerInput' export { default as MascotsInput } from './MascotsInput' +export { default as EditableKeyword } from './EditableKeyword' From 401c980e9972649d2c79d18081362851d5d13990 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sat, 14 Dec 2019 02:06:52 +0300 Subject: [PATCH 066/101] Fix mascots setting so it accepts array data --- src/store/modules/normalizers.js | 6 +- .../inputComponents/MascotsInput.vue | 60 ++++++++++++------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index c9dbc850..43a56a06 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -10,8 +10,10 @@ export const parseTuples = (tuples, key) => { return tuples.reduce((accum, item) => { if (key === 'rate_limit') { accum[item.tuple[0]] = item.tuple[1] - } else if (key === ':mascots') { - accum[item.tuple[0]] = { ...item.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` } + } else if (item.tuple[0] === ':mascots') { + accum[item.tuple[0]] = item.tuple[1].reduce((acc, mascot) => { + return [...acc, { [mascot.tuple[0]]: { ...mascot.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] + }, []) } else if (item.tuple[0] === ':groups') { accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => { return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] diff --git a/src/views/settings/components/inputComponents/MascotsInput.vue b/src/views/settings/components/inputComponents/MascotsInput.vue index 40b68500..6397a8e1 100644 --- a/src/views/settings/components/inputComponents/MascotsInput.vue +++ b/src/views/settings/components/inputComponents/MascotsInput.vue @@ -1,17 +1,17 @@ + + diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js index 511864e8..601f47d0 100644 --- a/src/views/settings/components/inputComponents/index.js +++ b/src/views/settings/components/inputComponents/index.js @@ -5,4 +5,5 @@ export { default as EditableKeywordInput } from './EditableKeywordInput' export { default as IconsInput } from './IconsInput' export { default as ProxyUrlInput } from './ProxyUrlInput' export { default as PruneInput } from './PruneInput' +export { default as RateLimitInput } from './RateLimitInput' export { default as SslOptionsInput } from './SslOptionsInput' diff --git a/src/views/settings/index.vue b/src/views/settings/index.vue index 16fd3dd5..90976b3d 100644 --- a/src/views/settings/index.vue +++ b/src/views/settings/index.vue @@ -53,13 +53,13 @@ + + +
From 2005467eaff7cd8f1b21a8e69d0faea40543cda7 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sun, 29 Dec 2019 21:10:58 +0300 Subject: [PATCH 086/101] Fix styles of nested settings --- src/views/settings/components/Inputs.vue | 31 +++++++++++++++++++++--- src/views/settings/styles/main.scss | 6 +++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 751ec913..1c4b6da2 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -1,5 +1,5 @@ @@ -104,6 +115,20 @@ export default { return {} } }, + inputClass: { + type: String, + default: function() { + return 'input-class' + }, + required: false + }, + labelClass: { + type: String, + default: function() { + return 'label' + }, + required: false + }, nested: { type: Boolean, default: function() { diff --git a/src/views/settings/styles/main.scss b/src/views/settings/styles/main.scss index b29e287c..45491ab8 100644 --- a/src/views/settings/styles/main.scss +++ b/src/views/settings/styles/main.scss @@ -23,6 +23,9 @@ .el-form-item { margin-right: 30px; } + .center-label label { + text-align: center; + } .el-input-group__prepend { padding-left: 10px; padding-right: 10px; @@ -76,6 +79,9 @@ .icons-container { display: flex; } + .keyword-inner-input { + margin-bottom: 22px; + } label { white-space: nowrap; overflow: hidden; From 1814e67adbe7f2dda5303c6045e1357d71fad79e Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Wed, 1 Jan 2020 17:37:27 +0700 Subject: [PATCH 087/101] Update processing nested values --- src/store/modules/normalizers.js | 44 ++++++++++++++++++ src/views/settings/components/Inputs.vue | 45 ++++++++----------- src/views/settings/components/Setting.vue | 2 +- .../inputComponents/SslOptionsInput.vue | 5 ++- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 1d3a3b23..e79fb043 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -3,6 +3,14 @@ const nonAtomsObjects = ['match_actor', ':match_actor'] const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits', 'styling'] const objectParents = ['mascots'] +const getCurrentValue = (object, keys) => { + if (keys.length === 0) { + return object + } + const [currentKey, ...restKeys] = keys + return getCurrentValue(object[currentKey], restKeys) +} + const getValueWithoutKey = (key, [type, value]) => { if (type === 'atom' && value.length > 1) { return `:${value}` @@ -124,6 +132,42 @@ export const partialUpdate = (group, key) => { return true } +export const processNested = (valueForState, valueForUpdatedSettings, group, parentKey, parents, settings, updatedSettings) => { + const [{ key, type }, ...otherParents] = parents + const path = [group, parentKey, ...parents.reverse().map(parent => parent.key)] + + const updatedValueForState = valueExists(settings, path) + ? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)), + ...{ [key]: valueForState }} + : { [key]: valueForState } + const updatedValueForUpdatedSettings = valueExists(updatedSettings, path) + ? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)), + ...{ [key]: [type, valueForUpdatedSettings] }} + : { [key]: [type, valueForUpdatedSettings] } + + // if (group === ':mime' && key === ':types') { + // updatedValueForState = { ...settings[group][key].value, ...updatedValueForState } + // updatedValueForUpdatedSettings = { + // ...Object.keys(settings[group][key].value) + // .reduce((acc, el) => { + // return { ...acc, [el]: [['list', 'string'], settings[group][key].value[el]] } + // }, {}), + // ...updatedValueForUpdatedSettings + // } + // } + return otherParents.length === 1 + ? { valueForState: updatedValueForState, valueForUpdatedSettings: updatedValueForUpdatedSettings, setting: otherParents[0] } + : processNested(updatedValueForState, updatedValueForUpdatedSettings, group, parentKey, otherParents, settings, updatedSettings) +} + +const valueExists = (value, path) => { + if (path.length === 0) { + return true + } + const [element, ...rest] = path + return value[element] ? valueExists(value[element], rest) : false +} + export const valueHasTuples = (key, value) => { const valueIsArrayOfNonObjects = Array.isArray(value) && value.length > 0 && value.every(el => typeof el !== 'object') return key === ':meta' || diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 1c4b6da2..fbe3a92b 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -59,11 +59,13 @@
+ :input-class="'keyword-inner-input'" + :nested="true"/>
@@ -86,6 +88,7 @@ import AceEditor from 'vue2-ace-editor' import 'brace/mode/elixir' import 'default-passive-events' import { AutoLinkerInput, BackendsLoggerInput, EditableKeywordInput, IconsInput, MascotsInput, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents' +import { processNested } from '@/store/modules/normalizers' export default { name: 'Inputs', @@ -148,9 +151,9 @@ export default { } }, settingParent: { - type: Object, + type: Array, default: function() { - return {} + return [] }, required: false } @@ -161,7 +164,7 @@ export default { return this.data[this.setting.key] ? this.data[this.setting.key][0] : '' }, set: function(value) { - this.processNestedData([value], this.settingGroup.group, this.settingGroup.key, this.settingParent.key, this.settingParent.type, this.setting.key, this.setting.type) + this.processNestedData([value], this.settingGroup.group, this.settingGroup.key, this.settingParent[0].key, this.settingParent[0].type) } }, inputValue() { @@ -174,7 +177,7 @@ export default { this.setting.key === 'Pleroma.Web.Auth.Authenticator' || this.setting.key === ':admin_token') { return this.data.value - } else if (this.settingGroup.group === ':mime' && this.settingParent.key === ':types') { + } else if (this.settingGroup.group === ':mime' && this.settingParent[0].key === ':types') { return this.data.value[this.setting.key] } else if (this.setting.type === 'atom') { return this.data[this.setting.key] && this.data[this.setting.key][0] === ':' ? this.data[this.setting.key].substr(1) : this.data[this.setting.key] @@ -202,27 +205,15 @@ export default { type === 'map' || (Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) }, - processNestedData(value, group, key, parentInput, parentType, childInput, childType) { - const valueExists = value => value[group] && value[group][key] && value[group][key][parentInput] - let updatedValueForState = valueExists(this.settings) - ? { ...this.settings[group][key][parentInput], ...{ [childInput]: value }} - : { [childInput]: value } - let updatedValue = valueExists(this.updatedSettings) - ? { ...this.updatedSettings[group][key][parentInput][1], ...{ [childInput]: [childType, value] }} - : { [childInput]: [childType, value] } + processNestedData(value, group, parentKey, parents) { + const { valueForState, + valueForUpdatedSettings, + setting } = processNested(value, value, group, parentKey, parents.reverse(), this.settings, this.updatedSettings) - if (group === ':mime' && parentInput === ':types') { - updatedValueForState = { ...this.settings[group][parentInput].value, ...updatedValueForState } - updatedValue = { - ...Object.keys(this.settings[group][parentInput].value) - .reduce((acc, el) => { - return { ...acc, [el]: [['list', 'string'], this.settings[group][parentInput].value[el]] } - }, {}), - ...updatedValue - } - } - this.$store.dispatch('UpdateSettings', { group, key, input: parentInput, value: updatedValue, type: parentType }) - this.$store.dispatch('UpdateState', { group, key, input: parentInput, value: updatedValueForState }) + this.$store.dispatch('UpdateSettings', + { group, key: parentKey, input: setting.key, value: valueForUpdatedSettings, type: setting.type }) + this.$store.dispatch('UpdateState', + { group, key: parentKey, input: setting.key, value: valueForState }) }, renderMultipleSelect(type) { return Array.isArray(type) && this.setting.key !== ':backends' && ( @@ -233,9 +224,9 @@ export default { this.setting.key === ':args' ) }, - update(value, group, key, parent, input, type, nested) { + update(value, group, key, parents, input, type, nested) { nested - ? this.processNestedData(value, group, key, parent.key, parent.type, input, type) + ? this.processNestedData(value, group, key, parents) : this.updateSetting(value, group, key, input, type) }, updateSetting(value, group, key, input, type) { diff --git a/src/views/settings/components/Setting.vue b/src/views/settings/components/Setting.vue index e9fca8d2..eb55030b 100644 --- a/src/views/settings/components/Setting.vue +++ b/src/views/settings/components/Setting.vue @@ -33,7 +33,7 @@
diff --git a/src/views/settings/components/inputComponents/SslOptionsInput.vue b/src/views/settings/components/inputComponents/SslOptionsInput.vue index ec80df2e..970ad9ba 100644 --- a/src/views/settings/components/inputComponents/SslOptionsInput.vue +++ b/src/views/settings/components/inputComponents/SslOptionsInput.vue @@ -4,7 +4,7 @@ Date: Fri, 3 Jan 2020 13:31:07 +0700 Subject: [PATCH 088/101] Fix processing nested data for dispatch setting --- src/store/modules/normalizers.js | 10 ++++++---- src/views/settings/components/Inputs.vue | 4 ++-- src/views/settings/components/Setting.vue | 2 +- src/views/settings/index.vue | 14 ++++++++------ 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index e79fb043..984062ff 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -134,18 +134,18 @@ export const partialUpdate = (group, key) => { export const processNested = (valueForState, valueForUpdatedSettings, group, parentKey, parents, settings, updatedSettings) => { const [{ key, type }, ...otherParents] = parents - const path = [group, parentKey, ...parents.reverse().map(parent => parent.key)] + const path = [group, parentKey, ...parents.reverse().map(parent => parent.key).slice(0, -1)] const updatedValueForState = valueExists(settings, path) ? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)), ...{ [key]: valueForState }} : { [key]: valueForState } const updatedValueForUpdatedSettings = valueExists(updatedSettings, path) - ? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)), + ? { ...getCurrentValue(updatedSettings[group][parentKey], parents.map(el => el.key).slice(0, -1))[1], ...{ [key]: [type, valueForUpdatedSettings] }} : { [key]: [type, valueForUpdatedSettings] } - // if (group === ':mime' && key === ':types') { + // if (group === ':mime' && key === ':types') { // updatedValueForState = { ...settings[group][key].value, ...updatedValueForState } // updatedValueForUpdatedSettings = { // ...Object.keys(settings[group][key].value) @@ -197,8 +197,10 @@ const wrapValues = (settings, currentState) => { return { 'tuple': [setting, wrapValues(value, currentState)] } } else if (type === 'atom' && value.length > 0) { return { 'tuple': [setting, `:${value}`] } - } else if (type.includes('tuple') && (type.includes('string') || type.includes('list') || type.includes('atom'))) { + } else if (type.includes('tuple') && (type.includes('string') || type.includes('atom'))) { return { 'tuple': [setting, { 'tuple': value }] } + } else if (type.includes('tuple') && type.includes('list')) { + return { 'tuple': [setting, value] } } else if (type === 'map') { const mapValue = Object.keys(value).reduce((acc, key) => { acc[key] = setting === ':match_actor' ? value[key] : value[key][1] diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index fbe3a92b..c707b859 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -59,7 +59,7 @@
diff --git a/src/views/settings/index.vue b/src/views/settings/index.vue index 14f34e40..91c73493 100644 --- a/src/views/settings/index.vue +++ b/src/views/settings/index.vue @@ -47,6 +47,9 @@ + @@ -59,18 +62,17 @@ + + + - + -->
From 218608e73ca028300e0670eeed14f7f0ffe19649 Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Fri, 3 Jan 2020 14:30:41 +0700 Subject: [PATCH 089/101] Fix processing nested data for mime types setting --- src/store/modules/normalizers.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 984062ff..120c3874 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -136,25 +136,26 @@ export const processNested = (valueForState, valueForUpdatedSettings, group, par const [{ key, type }, ...otherParents] = parents const path = [group, parentKey, ...parents.reverse().map(parent => parent.key).slice(0, -1)] - const updatedValueForState = valueExists(settings, path) + let updatedValueForState = valueExists(settings, path) ? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)), ...{ [key]: valueForState }} : { [key]: valueForState } - const updatedValueForUpdatedSettings = valueExists(updatedSettings, path) + let updatedValueForUpdatedSettings = valueExists(updatedSettings, path) ? { ...getCurrentValue(updatedSettings[group][parentKey], parents.map(el => el.key).slice(0, -1))[1], ...{ [key]: [type, valueForUpdatedSettings] }} : { [key]: [type, valueForUpdatedSettings] } - // if (group === ':mime' && key === ':types') { - // updatedValueForState = { ...settings[group][key].value, ...updatedValueForState } - // updatedValueForUpdatedSettings = { - // ...Object.keys(settings[group][key].value) - // .reduce((acc, el) => { - // return { ...acc, [el]: [['list', 'string'], settings[group][key].value[el]] } - // }, {}), - // ...updatedValueForUpdatedSettings - // } - // } + if (group === ':mime' && parents[0].key === ':types') { + updatedValueForState = { ...settings[group][parents[0].key].value, ...updatedValueForState } + updatedValueForUpdatedSettings = { + ...Object.keys(settings[group][parents[0].key].value) + .reduce((acc, el) => { + return { ...acc, [el]: [type, settings[group][parents[0].key].value[el]] } + }, {}), + ...updatedValueForUpdatedSettings + } + } + return otherParents.length === 1 ? { valueForState: updatedValueForState, valueForUpdatedSettings: updatedValueForUpdatedSettings, setting: otherParents[0] } : processNested(updatedValueForState, updatedValueForUpdatedSettings, group, parentKey, otherParents, settings, updatedSettings) From c48b08efee3bc3c30a82cdcbdb088073697264ac Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Fri, 3 Jan 2020 17:00:20 +0700 Subject: [PATCH 090/101] Improve processing multiple selects with array values --- src/store/modules/normalizers.js | 22 +++++-- src/store/modules/settings.js | 2 +- src/views/settings/components/Inputs.vue | 8 +-- .../inputComponents/BackendsLoggerInput.vue | 49 --------------- .../inputComponents/MultipleSelect.vue | 63 +++++++++++++++++++ .../components/inputComponents/index.js | 4 +- src/views/settings/index.vue | 8 +-- 7 files changed, 91 insertions(+), 65 deletions(-) delete mode 100644 src/views/settings/components/inputComponents/BackendsLoggerInput.vue create mode 100644 src/views/settings/components/inputComponents/MultipleSelect.vue diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 120c3874..d4dcbc1f 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -31,9 +31,14 @@ export const parseNonTuples = (key, value) => { if (key === ':backends') { const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes(':ex_syslogger')) const updated = value.map((el, i) => i === index ? ':ex_syslogger' : el) - return { value: updated } + return updated } - return { value } + if (key === ':args') { + const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes('implode')) + const updated = value.map((el, i) => i === index ? 'implode' : el) + return updated + } + return value } // REFACTOR export const parseTuples = (tuples, key) => { @@ -64,9 +69,11 @@ export const parseTuples = (tuples, key) => { accum[item.tuple[0]] = item.tuple[1] === ':disabled' ? [item.tuple[1]] : item.tuple[1].tuple } else if (item.tuple[0] === ':proxy_url') { accum[item.tuple[0]] = parseProxyUrl(item.tuple[1]) - } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) || // should be removed + } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) || (item.tuple[0] === ':tlsopts' && item.tuple[1].length === 0)) { accum[item.tuple[0]] = {} + } else if (item.tuple[0] === ':args') { + accum[item.tuple[0]] = parseNonTuples(item.tuple[0], item.tuple[1]) } else if (Array.isArray(item.tuple[1]) && (typeof item.tuple[1][0] === 'object' && !Array.isArray(item.tuple[1][0])) && item.tuple[1][0]['tuple']) { accum[item.tuple[0]] = parseTuples(item.tuple[1], item.tuple[0]) @@ -193,7 +200,7 @@ export const wrapUpdatedSettings = (group, settings, currentState) => { const wrapValues = (settings, currentState) => { return Object.keys(settings).map(setting => { - const [type, value] = Array.isArray(settings[setting]) ? settings[setting] : ['', settings[setting]] + const [type, value] = settings[setting] if (type === 'keyword' || type.includes('keyword') || setting === ':replace') { return { 'tuple': [setting, wrapValues(value, currentState)] } } else if (type === 'atom' && value.length > 0) { @@ -218,6 +225,13 @@ const wrapValues = (settings, currentState) => { return { 'tuple': [setting, { 'tuple': ip }] } } else if (setting === ':ssl_options') { return { 'tuple': [setting, wrapValues(value, currentState)] } + } else if (setting === ':args') { + const index = value.findIndex(el => el === 'implode') + const updatedArray = value.slice() + if (index !== -1) { + updatedArray[index] = { 'tuple': ['implode', '1'] } + } + return { 'tuple': [setting, updatedArray] } } else { return { 'tuple': [setting, value] } } diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index f7d1df79..406bd46d 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -36,7 +36,7 @@ const settings = { SET_SETTINGS: (state, data) => { const newSettings = data.reduce((acc, { group, key, value }) => { const parsedValue = valueHasTuples(key, value) - ? parseNonTuples(key, value) + ? { value: parseNonTuples(key, value) } : parseTuples(value, key) acc[group][key] = { ...acc[group][key], ...parsedValue } return acc diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index c707b859..90d66e46 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -75,7 +75,7 @@ - + @@ -87,7 +87,7 @@ import AceEditor from 'vue2-ace-editor' import 'brace/mode/elixir' import 'default-passive-events' -import { AutoLinkerInput, BackendsLoggerInput, EditableKeywordInput, IconsInput, MascotsInput, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents' +import { AutoLinkerInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents' import { processNested } from '@/store/modules/normalizers' export default { @@ -95,10 +95,10 @@ export default { components: { editor: AceEditor, AutoLinkerInput, - BackendsLoggerInput, EditableKeywordInput, IconsInput, MascotsInput, + MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput, @@ -216,7 +216,7 @@ export default { { group, key: parentKey, input: setting.key, value: valueForState }) }, renderMultipleSelect(type) { - return Array.isArray(type) && this.setting.key !== ':backends' && ( + return Array.isArray(type) && this.setting.key !== ':backends' && this.setting.key !== ':args' && ( type.includes('module') || (type.includes('list') && type.includes('string')) || (type.includes('list') && type.includes('atom')) || diff --git a/src/views/settings/components/inputComponents/BackendsLoggerInput.vue b/src/views/settings/components/inputComponents/BackendsLoggerInput.vue deleted file mode 100644 index da6af188..00000000 --- a/src/views/settings/components/inputComponents/BackendsLoggerInput.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - diff --git a/src/views/settings/components/inputComponents/MultipleSelect.vue b/src/views/settings/components/inputComponents/MultipleSelect.vue new file mode 100644 index 00000000..bcb766fa --- /dev/null +++ b/src/views/settings/components/inputComponents/MultipleSelect.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js index 601f47d0..faf7c1f8 100644 --- a/src/views/settings/components/inputComponents/index.js +++ b/src/views/settings/components/inputComponents/index.js @@ -1,8 +1,8 @@ export { default as AutoLinkerInput } from './AutoLinkerInput' -export { default as BackendsLoggerInput } from './BackendsLoggerInput' -export { default as MascotsInput } from './MascotsInput' export { default as EditableKeywordInput } from './EditableKeywordInput' export { default as IconsInput } from './IconsInput' +export { default as MascotsInput } from './MascotsInput' +export { default as MultipleSelect } from './MultipleSelect' export { default as ProxyUrlInput } from './ProxyUrlInput' export { default as PruneInput } from './PruneInput' export { default as RateLimitInput } from './RateLimitInput' diff --git a/src/views/settings/index.vue b/src/views/settings/index.vue index 91c73493..5be2da66 100644 --- a/src/views/settings/index.vue +++ b/src/views/settings/index.vue @@ -65,14 +65,12 @@ - - - - + + +
From a1c8fe84a3dc761828af7af8af92add285dbae6a Mon Sep 17 00:00:00 2001 From: Angelina Filippova Date: Sun, 5 Jan 2020 12:30:16 +0700 Subject: [PATCH 091/101] Fix proxy_url input for Upload tab --- src/store/modules/normalizers.js | 7 +-- src/views/settings/components/Inputs.vue | 2 +- .../inputComponents/ProxyUrlInput.vue | 47 +++++++++++++++---- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index d4dcbc1f..1b5c585e 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -132,8 +132,7 @@ const parseProxyUrl = value => { } export const partialUpdate = (group, key) => { - if ((group === ':pleroma' && key === 'Oban') || - (group === ':auto_linker' && key === ':opts')) { + if (group === ':auto_linker' && key === ':opts') { return false } return true @@ -206,7 +205,9 @@ const wrapValues = (settings, currentState) => { } else if (type === 'atom' && value.length > 0) { return { 'tuple': [setting, `:${value}`] } } else if (type.includes('tuple') && (type.includes('string') || type.includes('atom'))) { - return { 'tuple': [setting, { 'tuple': value }] } + return typeof value === 'string' + ? { 'tuple': [setting, value] } + : { 'tuple': [setting, { 'tuple': value }] } } else if (type.includes('tuple') && type.includes('list')) { return { 'tuple': [setting, value] } } else if (type === 'map') { diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index 90d66e46..cfb6d09d 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -73,7 +73,7 @@ - + diff --git a/src/views/settings/components/inputComponents/ProxyUrlInput.vue b/src/views/settings/components/inputComponents/ProxyUrlInput.vue index 7848fe15..83829bd5 100644 --- a/src/views/settings/components/inputComponents/ProxyUrlInput.vue +++ b/src/views/settings/components/inputComponents/ProxyUrlInput.vue @@ -1,20 +1,22 @@