Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pleroma/admin-fe
  • linafilippova/admin-fe
  • Exilat_a_Tolosa/admin-fe
  • mkljczk/admin-fe
  • maxf/admin-fe
  • kphrx/admin-fe
  • vaartis/admin-fe
  • ELR/admin-fe
  • eugenijm/admin-fe
  • jp/admin-fe
  • mkfain/admin-fe
  • lorenzoancora/admin-fe
  • alexgleason/admin-fe
  • seanking/admin-fe
  • ilja/admin-fe
15 results
Show changes
Showing
with 631 additions and 1358 deletions
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { baseName } from './utils' import { baseName } from './utils'
...@@ -11,23 +14,23 @@ export async function fetchRelays(authHost, token) { ...@@ -11,23 +14,23 @@ export async function fetchRelays(authHost, token) {
}) })
} }
export async function addRelay(relay, authHost, token) { export async function addRelay(relay_url, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: '/api/pleroma/admin/relay', url: '/api/pleroma/admin/relay',
method: 'post', method: 'post',
headers: authHeaders(token), headers: authHeaders(token),
data: { relay_url: relay } data: { relay_url }
}) })
} }
export async function deleteRelay(relay, authHost, token) { export async function deleteRelay(relay_url, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: '/api/pleroma/admin/relay', url: '/api/pleroma/admin/relay',
method: 'delete', method: 'delete',
headers: authHeaders(token), headers: authHeaders(token),
data: { relay_url: `https://${relay}/actor` } data: { relay_url }
}) })
} }
......
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { baseName } from './utils' import { baseName } from './utils'
...@@ -24,6 +27,15 @@ export async function fetchReports(filter, page, pageSize, authHost, token) { ...@@ -24,6 +27,15 @@ export async function fetchReports(filter, page, pageSize, authHost, token) {
}) })
} }
export async function fetchSingleReport(id, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/reports/${id}`,
method: 'get',
headers: authHeaders(token)
})
}
export async function createNote(content, reportID, authHost, token) { export async function createNote(content, reportID, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
......
export const reports = [
{
id: '1',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #1', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '1', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '2', timestamp: '2019/4/13' }
]
},
{
id: '2',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #2',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '3', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '4', timestamp: '2019/4/3' }
]
},
{
id: '3',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #3',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '5', timestamp: '2019/3/1' }]
},
{
id: '4',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #4', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '6', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '7', timestamp: '2019/4/13' }
]
},
{
id: '5',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #5',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '8', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '9', timestamp: '2019/4/3' }
]
},
{
id: '6',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #6',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '10', timestamp: '2019/3/1' }]
},
{
id: '7',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #7', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '11', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '12', timestamp: '2019/4/13' }
]
},
{
id: '8',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #8',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '13', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '14', timestamp: '2019/4/3' }
]
},
{
id: '9',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #9',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '15', timestamp: '2019/3/1' }]
},
{
id: '10',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #10', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '16', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '17', timestamp: '2019/4/13' }
]
},
{
id: '11',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #11',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '18', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '19', timestamp: '2019/4/3' }
]
},
{
id: '12',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #12',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '20', timestamp: '2019/3/1' }]
},
{
id: '13',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #13', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '21', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '22', timestamp: '2019/4/13' }
]
},
{
id: '14',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #14',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '23', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '24', timestamp: '2019/4/3' }
]
},
{
id: '15',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #15',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '25', timestamp: '2019/3/1' }]
},
{
id: '16',
timestamp: '2019/4/12',
local: true,
from: 'John', // actor nickname
object: 'Bob', // user nickname
header: 'Report #16', // content
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Nick', text: 'Lorem ipsum', id: '26', timestamp: '2019/4/13' },
{ author: 'Val', text: 'dolor sit amet', id: '27', timestamp: '2019/4/13' }
]
},
{
id: '17',
timestamp: '2019/4/1',
local: true,
from: 'Max',
object: 'Vic',
header: 'Report #17',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '28', timestamp: '2019/4/2' },
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '29', timestamp: '2019/4/3' }
]
},
{
id: '18',
timestamp: '2019/2/28',
local: true,
from: 'Tim',
object: 'Jen',
header: 'Report #18',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '30', timestamp: '2019/3/1' }]
}
]
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { baseName } from './utils' import { baseName } from './utils'
import _ from 'lodash'
export async function deleteInstanceDocument(name, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/instance_document/${name}`,
method: 'delete',
headers: authHeaders(token)
})
}
export async function fetchDescription(authHost, token) { export async function fetchDescription(authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: `/api/pleroma/admin/config/descriptions`, url: `/api/v1/pleroma/admin/config/descriptions`,
method: 'get',
headers: authHeaders(token)
})
}
export async function fetchDescription2(authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/v2/pleroma/admin/config/descriptions`,
method: 'get', method: 'get',
headers: authHeaders(token) headers: authHeaders(token)
}) })
...@@ -20,6 +42,25 @@ export async function fetchSettings(authHost, token) { ...@@ -20,6 +42,25 @@ export async function fetchSettings(authHost, token) {
}) })
} }
export async function getInstanceDocument(name, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/instance_document/${name}`,
method: 'get',
headers: authHeaders(token)
})
}
export async function updateInstanceDocument(name, formData, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/instance_document/${name}`,
method: 'patch',
data: formData,
headers: { ...authHeaders(token), 'Content-Type': 'multipart/form-data' }
})
}
export async function updateSettings(configs, authHost, token) { export async function updateSettings(configs, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
...@@ -40,13 +81,24 @@ export async function removeSettings(configs, authHost, token) { ...@@ -40,13 +81,24 @@ export async function removeSettings(configs, authHost, token) {
}) })
} }
export async function restartApp(authHost, token) { export async function fetchFrontends(authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: `/api/pleroma/admin/restart`, url: `/api/pleroma/admin/frontends`,
method: 'get', method: 'get',
headers: authHeaders(token) headers: authHeaders(token)
}) })
} }
export async function installFrontend(data, authHost, token) {
const filteredData = _.pickBy(data)
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/frontends/install`,
method: 'post',
headers: authHeaders(token),
data: filteredData
})
}
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {} const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { baseName } from './utils' import { baseName } from './utils'
...@@ -21,6 +24,15 @@ export async function deleteStatus(id, authHost, token) { ...@@ -21,6 +24,15 @@ export async function deleteStatus(id, authHost, token) {
}) })
} }
export async function fetchStatus(id, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/statuses/${id}`,
method: 'get',
headers: authHeaders(token)
})
}
export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) { export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
...@@ -30,6 +42,15 @@ export async function fetchStatuses({ godmode, localOnly, authHost, token, pageS ...@@ -30,6 +42,15 @@ export async function fetchStatuses({ godmode, localOnly, authHost, token, pageS
}) })
} }
export async function fetchStatusesCount(instance, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: instance ? `/api/pleroma/admin/stats?instance=${instance}` : `/api/pleroma/admin/stats`,
method: 'get',
headers: authHeaders(token)
})
}
export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) { export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
......
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { baseName } from './utils' import { baseName } from './utils'
...@@ -62,6 +65,16 @@ export async function deleteUsers(nicknames, authHost, token) { ...@@ -62,6 +65,16 @@ export async function deleteUsers(nicknames, authHost, token) {
}) })
} }
export async function disableMfa(nickname, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/disable_mfa`,
method: 'put',
headers: authHeaders(token),
data: { nickname }
})
}
export async function fetchUser(id, authHost, token) { export async function fetchUser(id, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
...@@ -71,10 +84,36 @@ export async function fetchUser(id, authHost, token) { ...@@ -71,10 +84,36 @@ export async function fetchUser(id, authHost, token) {
}) })
} }
export async function fetchUsers(filters, authHost, token, page = 1) { export async function fetchUserCredentials(nickname, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: `/api/pleroma/admin/users?page=${page}&filters=${filters}`, url: `/api/pleroma/admin/users/${nickname}/credentials`,
method: 'get',
headers: authHeaders(token)
})
}
export async function updateUserCredentials(nickname, credentials, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/${nickname}/credentials`,
method: 'patch',
headers: authHeaders(token),
data: credentials
})
}
export async function fetchUsers(filters, actorTypeFilters, authHost, token, page = 1) {
const url = actorTypeFilters.length === 0
? `/api/pleroma/admin/users?page=${page}&filters=${filters}`
: actorTypeFilters.reduce((acc, filter) => {
const newAcc = acc.concat(`&actor_types[]=${filter}`)
return newAcc
}, `/api/pleroma/admin/users?page=${page}&filters=${filters}`)
return await request({
baseURL: baseName(authHost),
url,
method: 'get', method: 'get',
headers: authHeaders(token) headers: authHeaders(token)
}) })
...@@ -99,10 +138,17 @@ export async function forcePasswordReset(nicknames, authHost, token) { ...@@ -99,10 +138,17 @@ export async function forcePasswordReset(nicknames, authHost, token) {
}) })
} }
export async function searchUsers(query, filters, authHost, token, page = 1) { export async function searchUsers(query, filters, actorTypeFilters, authHost, token, page = 1) {
const url = actorTypeFilters.length === 0
? `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`
: actorTypeFilters.reduce((acc, filter) => {
const newAcc = acc.concat(`&actor_types[]=${filter}`)
return newAcc
}, `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`)
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
url: `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`, url,
method: 'get', method: 'get',
headers: authHeaders(token) headers: authHeaders(token)
}) })
...@@ -137,6 +183,25 @@ export async function fetchUserStatuses(id, authHost, godmode, token) { ...@@ -137,6 +183,25 @@ export async function fetchUserStatuses(id, authHost, godmode, token) {
}) })
} }
export async function fetchUserChats(id, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/${id}/chats`,
method: 'get',
headers: authHeaders(token)
})
}
export async function approveUserAccount(nicknames, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: '/api/pleroma/admin/users/approve',
method: 'patch',
headers: authHeaders(token),
data: { nicknames }
})
}
export async function confirmUserEmail(nicknames, authHost, token) { export async function confirmUserEmail(nicknames, authHost, token) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),
......
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only
const isLocalhost = (instanceName) => const isLocalhost = (instanceName) =>
instanceName.startsWith('localhost:') || instanceName.startsWith('127.0.0.1:') instanceName.startsWith('localhost:') || instanceName.startsWith('127.0.0.1:')
......
src/assets/404_images/404.png

95.8 KiB

src/assets/404_images/404_cloud.png

4.65 KiB

This diff is collapsed.
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<el-card v-if="!message.deleted" class="message-card">
<div slot="header">
<div class="message-header">
<div class="message-meta">
<router-link
v-if="propertyExists(author, 'id')"
:to="{ name: 'UsersShow', params: { id: author.id }}"
class="router-link"
@click.native.stop>
<div class="message-author">
<img v-if="propertyExists(author, 'avatar')" :src="author.avatar" class="message-author-avatar-img">
<span v-if="propertyExists(author, 'username')" class="message-author-name">{{ author.username }}</span>
<span v-else>
<span v-if="propertyExists(author, 'username')" class="message-author-name">
{{ author.username }}
</span>
<span v-else class="message-author-name deactivated">({{ $t('users.invalidNickname') }})</span>
</span>
</div>
</router-link>
<span class="message-timestamp">{{ parseTimestamp(message.created_at) }}</span>
</div>
<div class="message-actions">
<el-dropdown trigger="click" @click.native.stop>
<el-button plain size="small" icon="el-icon-edit" class="status-actions-button">
{{ $t('reports.messageModeration') }}<i class="el-icon-arrow-down el-icon--right"/>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
@click.native="deleteMessage()">
{{ $t('reports.deleteMessage') }}
</el-dropdown-item>
<el-dropdown-item
@click.native="handleRouteChange()">
{{ $t('users.moderateUser') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<div class="message-body">
<span class="message-content" v-html="message.content"/>
<div v-if="message.attachment" class="image">
<img :src="message.attachment.preview_url">
</div>
</div>
</el-card>
</template>
<script>
import { DateTime } from 'luxon'
export default {
name: 'ChatMessage',
props: {
message: {
type: Object,
required: true
},
author: {
type: Object,
required: true
},
page: {
type: Number,
required: false,
default: 0
}
},
data() {
return {
}
},
methods: {
propertyExists(account, property) {
return account[property]
},
parseTimestamp(timestamp) {
return DateTime.fromISO(timestamp).toFormat('yyyy-MM-dd HH:mm')
},
deleteMessage() {
this.$confirm('Are you sure you want to delete this message?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
this.$store.dispatch('DeleteMessage', {
chat_id: this.message.chat_id,
message_id: this.message.id
})
this.$message({
type: 'success',
message: 'Delete completed'
})
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
})
})
},
handleRouteChange() {
this.$router.push({ name: 'UsersShow', params: { id: this.author.id }})
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
.message-card {
margin-bottom: 10px;
.account {
line-height: 26px;
font-size: 13px;
color: #606266;
}
.account:hover {
text-decoration: underline;
}
.deactivated {
color: gray;
line-height: 28px;
vertical-align: middle;
}
.image {
width: 20%;
img {
width: 100%;
}
}
.router-link {
text-decoration: none;
}
.show-more-button {
margin-left: 5px;
}
.message-author {
display: flex;
align-items: center;
}
.message-author-avatar-img {
display: inline-block;
width: 15px;
height: 15px;
margin-right: 5px;
}
.message-author-name {
display: inline-block;
margin: 0;
font-size: 15px;
font-weight: 500;
}
.message-body {
display: flex;
flex-direction: column;
}
.message-card-header {
display: flex;
align-items: center;
}
.chat-content {
font-size: 15px;
line-height: 26px;
}
.message-timestamp {
font-size: 13px;
color: #606266;
margin-left: 20px;
}
.message-deleted {
font-style: italic;
margin-top: 3px;
}
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
.message-meta {
display: flex;
justify-content: flex-start;
align-items: flex-end;
}
}
}
@media only screen and (max-width:480px) {
.el-message {
min-width: 80%;
}
.el-message-box {
width: 80%;
}
.message-card {
.el-card__header {
padding: 10px 17px;
}
.el-tag {
margin: 3px 0;
}
.message-author-container {
margin-bottom: 5px;
}
.message-action-buttons {
margin: 3px 0 3px;
}
.message-actions {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.message-header {
display: flex;
flex-direction: column;
align-items: flex-start;
}
}
.message-actions-button {
margin: 3px 0 3px;
}
.message-actions {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
}
</style>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<el-tooltip v-if="needReboot" :content="$t('settings.restartApp')" placement="bottom-end">
<el-button type="warning" class="reboot-button" @click="restartApp">
<span>
<i class="el-icon-refresh"/>
{{ $t('settings.instanceReboot') }}
</span>
</el-button>
</el-tooltip>
</template>
<script>
import i18n from '@/lang'
export default {
name: 'RebootButton',
computed: {
needReboot() {
return this.$store.state.app.needReboot
}
},
methods: {
async restartApp() {
try {
await this.$store.dispatch('RestartApplication')
} catch (e) {
return
}
this.$message({
type: 'success',
message: i18n.t('settings.restartSuccess')
})
}
}
}
</script>
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->
<template> <template>
<div> <el-card v-if="!status.deleted" class="status-card" @click.native="handleRouteChange()">
<el-card v-if="!status.deleted" class="status-card"> <div slot="header">
<div slot="header"> <div class="status-header">
<div class="status-header"> <div class="status-account-container">
<div class="status-account-container"> <div class="status-account">
<div class="status-account"> <el-checkbox v-if="showCheckbox" class="status-checkbox" @change="handleStatusSelection(account)"/>
<el-checkbox v-if="showCheckbox" class="status-checkbox" @change="handleStatusSelection(status.account)"/> <router-link
<img :src="status.account.avatar" class="status-avatar-img"> v-if="propertyExists(account, 'id')"
<h3 class="status-account-name">{{ status.account.display_name }}</h3> :to="{ name: 'UsersShow', params: { id: account.id }}"
</div> class="router-link"
<a :href="status.account.url" target="_blank" class="account"> @click.native.stop>
@{{ status.account.acct }} <div class="status-card-header">
</a> <img v-if="propertyExists(account, 'avatar')" :src="account.avatar" class="status-avatar-img">
<span v-if="propertyExists(account, 'nickname')" class="status-account-name">{{ account.nickname }}</span>
<span v-else>
<span v-if="propertyExists(account, 'nickname')" class="status-account-name">
{{ account.nickname }}
</span>
<span v-else class="status-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
</span>
</div>
</router-link>
</div> </div>
<div class="status-actions"> </div>
<div v-if="isPrivileged(['messages_delete'], [])" class="status-actions">
<div class="status-tags">
<el-tag v-if="status.sensitive" type="warning" size="large">{{ $t('reports.sensitive') }}</el-tag> <el-tag v-if="status.sensitive" type="warning" size="large">{{ $t('reports.sensitive') }}</el-tag>
<el-tag size="large">{{ capitalizeFirstLetter(status.visibility) }}</el-tag> <el-tag size="large">{{ capitalizeFirstLetter(status.visibility) }}</el-tag>
<el-dropdown trigger="click">
<el-button plain size="small" icon="el-icon-edit" class="status-actions-button">
{{ $t('reports.changeScope') }}<i class="el-icon-arrow-down el-icon--right"/>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-if="!status.sensitive"
@click.native="changeStatus(status.id, true, status.visibility)">
{{ $t('reports.addSensitive') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.sensitive"
@click.native="changeStatus(status.id, false, status.visibility)">
{{ $t('reports.removeSensitive') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'public'"
@click.native="changeStatus(status.id, status.sensitive, 'public')">
{{ $t('reports.public') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'private'"
@click.native="changeStatus(status.id, status.sensitive, 'private')">
{{ $t('reports.private') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'unlisted'"
@click.native="changeStatus(status.id, status.sensitive, 'unlisted')">
{{ $t('reports.unlisted') }}
</el-dropdown-item>
<el-dropdown-item
@click.native="deleteStatus(status.id)">
{{ $t('reports.deleteStatus') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div> </div>
<el-dropdown trigger="click" @click.native.stop>
<el-button plain size="small" icon="el-icon-edit" class="status-actions-button">
{{ $t('reports.changeScope') }}<i class="el-icon-arrow-down el-icon--right"/>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-if="!status.sensitive"
@click.native="changeStatus(status.id, true, status.visibility)">
{{ $t('reports.addSensitive') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.sensitive"
@click.native="changeStatus(status.id, false, status.visibility)">
{{ $t('reports.removeSensitive') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'public'"
@click.native="changeStatus(status.id, status.sensitive, 'public')">
{{ $t('reports.public') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'private'"
@click.native="changeStatus(status.id, status.sensitive, 'private')">
{{ $t('reports.private') }}
</el-dropdown-item>
<el-dropdown-item
v-if="status.visibility !== 'unlisted'"
@click.native="changeStatus(status.id, status.sensitive, 'unlisted')">
{{ $t('reports.unlisted') }}
</el-dropdown-item>
<el-dropdown-item
@click.native="deleteStatus(status.id)">
{{ $t('reports.deleteStatus') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div> </div>
</div> </div>
<div class="status-body"> </div>
<div v-if="status.spoiler_text"> <div class="status-body">
<strong>{{ status.spoiler_text }}</strong> <div v-if="status.spoiler_text">
<el-button v-if="!showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = true">Show more</el-button> <strong>{{ status.spoiler_text }}</strong>
<el-button v-if="showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = false">Show less</el-button> <el-button v-if="!showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = true">Show more</el-button>
<div v-if="showHiddenStatus"> <el-button v-if="showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = false">Show less</el-button>
<span class="status-content" v-html="status.content"/> <div v-if="showHiddenStatus">
<div v-if="status.poll" class="poll">
<ul>
<li v-for="(option, index) in status.poll.options" :key="index">
{{ option.title }}
<el-progress :percentage="optionPercent(status.poll, option)" />
</li>
</ul>
</div>
<div v-for="(attachment, index) in status.media_attachments" :key="index" class="image">
<img :src="attachment.preview_url">
</div>
</div>
</div>
<div v-if="!status.spoiler_text">
<span class="status-content" v-html="status.content"/> <span class="status-content" v-html="status.content"/>
<div v-if="status.poll" class="poll"> <div v-if="status.poll" class="poll">
<ul> <ul>
...@@ -89,38 +91,64 @@ ...@@ -89,38 +91,64 @@
<img :src="attachment.preview_url"> <img :src="attachment.preview_url">
</div> </div>
</div> </div>
<a :href="status.url" target="_blank" class="account"> </div>
{{ parseTimestamp(status.created_at) }} <div v-if="!status.spoiler_text">
<span class="status-content" v-html="status.content"/>
<div v-if="status.poll" class="poll">
<ul>
<li v-for="(option, index) in status.poll.options" :key="index">
{{ option.title }}
<el-progress :percentage="optionPercent(status.poll, option)" />
</li>
</ul>
</div>
<div v-for="(attachment, index) in status.media_attachments" :key="index" class="image">
<img :src="attachment.preview_url">
</div>
</div>
<div class="status-footer">
<span class="status-created-at">{{ parseTimestamp(status.created_at) }}</span>
<a v-if="status.url" :href="status.url" target="_blank" class="account" @click.stop>
{{ $t('statuses.openStatusInInstance') }}
<i class="el-icon-top-right"/>
</a> </a>
</div> </div>
</el-card> </div>
<el-card v-else class="status-card"> </el-card>
<div slot="header"> <el-card v-else class="status-card">
<div class="status-header"> <div slot="header">
<div class="status-account-container"> <div class="status-header">
<div class="status-account"> <div class="status-account-container">
<h4 class="status-deleted">{{ $t('reports.statusDeleted') }}</h4> <div class="status-account">
</div> <h4 class="status-deleted">{{ $t('reports.statusDeleted') }}</h4>
</div> </div>
</div> </div>
</div> </div>
<div class="status-body"> </div>
<span v-if="status.content" class="status-content" v-html="status.content"/> <div class="status-body">
<span v-else class="status-without-content">no content</span> <span v-if="status.content" class="status-content" v-html="status.content"/>
</div> <span v-else class="status-without-content">no content</span>
<a v-if="status.created_at" :href="status.url" target="_blank" class="account"> </div>
{{ parseTimestamp(status.created_at) }} <div class="status-footer">
<span v-if="status.created_at" class="status-created-at">{{ parseTimestamp(status.created_at) }}</span>
<a v-if="status.url" :href="status.url" target="_blank" class="account" @click.stop>
Open status in instance
<i class="el-icon-top-right"/>
</a> </a>
</el-card> </div>
</div> </el-card>
</template> </template>
<script> <script>
import moment from 'moment' import { DateTime } from 'luxon'
export default { export default {
name: 'Status', name: 'Status',
props: { props: {
account: {
type: Object,
required: false,
default: () => { return {} }
},
fetchStatusesByInstance: { fetchStatusesByInstance: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -160,6 +188,11 @@ export default { ...@@ -160,6 +188,11 @@ export default {
capitalizeFirstLetter(str) { capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1) return str.charAt(0).toUpperCase() + str.slice(1)
}, },
isPrivileged(accepted_privileges, accepted_roles) {
const user_privileges = this.$store.getters.privileges
const user_roles = this.$store.getters.roles
return accepted_privileges.some(privilege => user_privileges.indexOf(privilege) >= 0) || accepted_roles.some(role => user_roles.indexOf(role) >= 0)
},
changeStatus(statusId, isSensitive, visibility) { changeStatus(statusId, isSensitive, visibility) {
this.$store.dispatch('ChangeStatusScope', { this.$store.dispatch('ChangeStatusScope', {
statusId, statusId,
...@@ -195,6 +228,12 @@ export default { ...@@ -195,6 +228,12 @@ export default {
}) })
}) })
}, },
handleStatusSelection(account) {
this.$emit('status-selection', account)
},
handleRouteChange() {
this.$router.push({ name: 'StatusShow', params: { id: this.status.id }})
},
optionPercent(poll, pollOption) { optionPercent(poll, pollOption) {
const allVotes = poll.options.reduce((acc, option) => (acc + option.votes_count), 0) const allVotes = poll.options.reduce((acc, option) => (acc + option.votes_count), 0)
if (allVotes === 0) { if (allVotes === 0) {
...@@ -203,10 +242,13 @@ export default { ...@@ -203,10 +242,13 @@ export default {
return +(pollOption.votes_count / allVotes * 100).toFixed(1) return +(pollOption.votes_count / allVotes * 100).toFixed(1)
}, },
parseTimestamp(timestamp) { parseTimestamp(timestamp) {
return moment(timestamp).format('YYYY-MM-DD HH:mm') return DateTime.fromISO(timestamp).toFormat('yyyy-MM-dd HH:mm')
}, },
handleStatusSelection(account) { propertyExists(account, property, _secondProperty) {
this.$emit('status-selection', account) if (_secondProperty) {
return account[property] && account[_secondProperty]
}
return account[property]
} }
} }
} }
...@@ -215,10 +257,19 @@ export default { ...@@ -215,10 +257,19 @@ export default {
<style rel='stylesheet/scss' lang='scss'> <style rel='stylesheet/scss' lang='scss'>
.status-card { .status-card {
margin-bottom: 10px; margin-bottom: 10px;
cursor: pointer;
.account { .account {
text-decoration: underline;
line-height: 26px; line-height: 26px;
font-size: 13px; font-size: 13px;
color: #606266;
}
.account:hover {
text-decoration: underline;
}
.deactivated {
color: gray;
line-height: 28px;
vertical-align: middle;
} }
.image { .image {
width: 20%; width: 20%;
...@@ -226,6 +277,9 @@ export default { ...@@ -226,6 +277,9 @@ export default {
width: 100%; width: 100%;
} }
} }
.router-link {
text-decoration: none;
}
.show-more-button { .show-more-button {
margin-left: 5px; margin-left: 5px;
} }
...@@ -242,12 +296,17 @@ export default { ...@@ -242,12 +296,17 @@ export default {
.status-account-name { .status-account-name {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
height: 22px; font-size: 15px;
font-weight: 500;
} }
.status-body { .status-body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.status-card-header {
display: flex;
align-items: center;
}
.status-checkbox { .status-checkbox {
margin-right: 7px; margin-right: 7px;
} }
...@@ -255,13 +314,26 @@ export default { ...@@ -255,13 +314,26 @@ export default {
font-size: 15px; font-size: 15px;
line-height: 26px; line-height: 26px;
} }
.status-created-at {
font-size: 13px;
color: #606266;
}
.status-deleted { .status-deleted {
font-style: italic; font-style: italic;
margin-top: 3px; margin-top: 3px;
} }
.status-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.status-header { .status-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
}
.status-tags {
display: inline;
} }
.status-without-content { .status-without-content {
font-style: italic; font-style: italic;
...@@ -280,7 +352,7 @@ export default { ...@@ -280,7 +352,7 @@ export default {
padding: 10px 17px; padding: 10px 17px;
} }
.el-tag { .el-tag {
margin: 3px 4px 3px 0; margin: 3px 0;
} }
.status-account-container { .status-account-container {
margin-bottom: 5px; margin-bottom: 5px;
...@@ -289,12 +361,20 @@ export default { ...@@ -289,12 +361,20 @@ export default {
margin: 3px 0 3px; margin: 3px 0 3px;
} }
.status-actions { .status-actions {
width: 100%;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between;
}
.status-footer {
flex-direction: column;
align-items: flex-start;
margin-top: 10px;
} }
.status-header { .status-header {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start;
} }
} }
} }
......
<template>
<transition :name="transitionName">
<div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop">
<svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height: 16px; width: 16px;">
<title>回到顶部</title>
<g>
<path d="M12.036 15.59c0 .55-.453.995-.997.995H5.032c-.55 0-.997-.445-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29c.39-.39 1.026-.385 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" fill-rule="evenodd"/>
</g>
</svg>
</div>
</transition>
</template>
<script>
export default {
name: 'BackToTop',
props: {
visibilityHeight: {
type: Number,
default: 400
},
backPosition: {
type: Number,
default: 0
},
customStyle: {
type: Object,
default: function() {
return {
right: '50px',
bottom: '50px',
width: '40px',
height: '40px',
'border-radius': '4px',
'line-height': '45px',
background: '#e7eaf1'
}
}
},
transitionName: {
type: String,
default: 'fade'
}
},
data: function() {
return {
visible: false,
interval: null,
isMoving: false
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
if (this.interval) {
clearInterval(this.interval)
}
},
methods: {
handleScroll() {
this.visible = window.pageYOffset > this.visibilityHeight
},
backToTop() {
if (this.isMoving) return
const start = window.pageYOffset
let i = 0
this.isMoving = true
this.interval = setInterval(() => {
const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500))
if (next <= this.backPosition) {
window.scrollTo(0, this.backPosition)
clearInterval(this.interval)
this.isMoving = false
} else {
window.scrollTo(0, next)
}
i++
}, 16.7)
},
easeInOutQuad(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b
return -c / 2 * (--t * (t - 2) - 1) + b
}
}
}
</script>
<style scoped>
.back-to-ceiling {
position: fixed;
display: inline-block;
text-align: center;
cursor: pointer;
}
.back-to-ceiling:hover {
background: #d5dbe7;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity .5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0
}
.back-to-ceiling .Icon {
fill: #9aaabf;
background: none;
}
</style>
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{
generateTitle(item.meta.title) }}</span>
<a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import { generateTitle } from '@/utils/i18n'
import pathToRegexp from 'path-to-regexp'
export default {
data: function() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
generateTitle,
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
const first = matched[0]
if (first && first.name.trim().toLocaleLowerCase() !== 'Dashboard'.toLocaleLowerCase()) {
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"/>
</template>
<script>
import echarts from 'echarts'
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data: function() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
const xAxisData = []
const data = []
const data2 = []
for (let i = 0; i < 50; i++) {
xAxisData.push(i)
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
}
this.chart.setOption(
{
backgroundColor: '#08263a',
grid: {
left: '5%',
right: '5%'
},
xAxis: [{
show: false,
data: xAxisData
}, {
show: false,
data: xAxisData
}],
visualMap: {
show: false,
min: 0,
max: 50,
dimension: 0,
inRange: {
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
}
},
yAxis: {
axisLine: {
show: false
},
axisLabel: {
textStyle: {
color: '#4a657a'
}
},
splitLine: {
show: true,
lineStyle: {
color: '#08263f'
}
},
axisTick: {
show: false
}
},
series: [{
name: 'back',
type: 'bar',
data: data2,
z: 1,
itemStyle: {
normal: {
opacity: 0.4,
barBorderRadius: 5,
shadowBlur: 3,
shadowColor: '#111'
}
}
}, {
name: 'Simulate Shadow',
type: 'line',
data,
z: 2,
showSymbol: false,
animationDelay: 0,
animationEasing: 'linear',
animationDuration: 1200,
lineStyle: {
normal: {
color: 'transparent'
}
},
areaStyle: {
normal: {
color: '#08263a',
shadowBlur: 50,
shadowColor: '#000'
}
}
}, {
name: 'front',
type: 'bar',
data,
xAxisIndex: 1,
z: 3,
itemStyle: {
normal: {
barBorderRadius: 5
}
}
}],
animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut',
animationDelay(idx) {
return idx * 20
},
animationDelayUpdate(idx) {
return idx * 20
}
})
}
}
}
</script>
This diff is collapsed.
This diff is collapsed.
import { debounce } from '@/utils'
export default {
data: function() {
return {
sidebarElm: null
}
},
mounted() {
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.__resizeHandler)
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
},
methods: {
sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.__resizeHandler()
}
}
}
}
This diff is collapsed.