feat: Add support to gRPC Business Data Client version 1.9.0 (#236)
parent
a3d3dd3a1f
commit
b160070320
|
@ -45,7 +45,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adempiere/grpc-access-client": "^1.1.8",
|
"@adempiere/grpc-access-client": "^1.1.8",
|
||||||
"@adempiere/grpc-data-client": "^1.8.8",
|
"@adempiere/grpc-data-client": "^1.9.0",
|
||||||
"@adempiere/grpc-dictionary-client": "^1.3.5",
|
"@adempiere/grpc-dictionary-client": "^1.3.5",
|
||||||
"@adempiere/grpc-enrollment-client": "^1.0.7",
|
"@adempiere/grpc-enrollment-client": "^1.0.7",
|
||||||
"autoprefixer": "^9.5.1",
|
"autoprefixer": "^9.5.1",
|
||||||
|
|
|
@ -80,14 +80,23 @@ export function getEntity({ tableName, recordId, recordUuid }) {
|
||||||
* @param {string} orderByClause
|
* @param {string} orderByClause
|
||||||
* @param {string} nextPageToken
|
* @param {string} nextPageToken
|
||||||
*/
|
*/
|
||||||
export function getEntitiesList({ tableName, query, whereClause, conditions: conditionsList = [], orderByClause, nextPageToken }) {
|
export function getEntitiesList({
|
||||||
|
tableName,
|
||||||
|
query,
|
||||||
|
whereClause,
|
||||||
|
conditions: conditionsList = [],
|
||||||
|
orderByClause,
|
||||||
|
nextPageToken: pageToken,
|
||||||
|
pageSize
|
||||||
|
}) {
|
||||||
return Instance.call(this).requestEntitiesList({
|
return Instance.call(this).requestEntitiesList({
|
||||||
tableName,
|
tableName,
|
||||||
query,
|
query,
|
||||||
whereClause,
|
whereClause,
|
||||||
conditionsList,
|
conditionsList,
|
||||||
orderByClause,
|
orderByClause,
|
||||||
nextPageToken
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +106,11 @@ export function getEntitiesList({ tableName, query, whereClause, conditions: con
|
||||||
* @param {number} recordId
|
* @param {number} recordId
|
||||||
* @param {string} eventType
|
* @param {string} eventType
|
||||||
*/
|
*/
|
||||||
export function rollbackEntity({ tableName, recordId, eventType }) {
|
export function rollbackEntity({
|
||||||
|
tableName,
|
||||||
|
recordId,
|
||||||
|
eventType
|
||||||
|
}) {
|
||||||
return Instance.call(this).rollbackEntityRequest({
|
return Instance.call(this).rollbackEntityRequest({
|
||||||
tableName,
|
tableName,
|
||||||
recordId,
|
recordId,
|
||||||
|
@ -112,7 +125,11 @@ export function rollbackEntity({ tableName, recordId, eventType }) {
|
||||||
* @param {string} directQuery
|
* @param {string} directQuery
|
||||||
* @param {string|number} value
|
* @param {string|number} value
|
||||||
*/
|
*/
|
||||||
export function getLookup({ tableName, directQuery, value }) {
|
export function getLookup({
|
||||||
|
tableName,
|
||||||
|
directQuery,
|
||||||
|
value
|
||||||
|
}) {
|
||||||
return Instance.call(this).requestLookupFromReference({
|
return Instance.call(this).requestLookupFromReference({
|
||||||
tableName,
|
tableName,
|
||||||
directQuery,
|
directQuery,
|
||||||
|
@ -126,10 +143,17 @@ export function getLookup({ tableName, directQuery, value }) {
|
||||||
* @param {string} tableName
|
* @param {string} tableName
|
||||||
* @param {string} query
|
* @param {string} query
|
||||||
*/
|
*/
|
||||||
export function getLookupList({ tableName, query }) {
|
export function getLookupList({
|
||||||
return Instance.call(this).requestLookupListFromReference({
|
tableName,
|
||||||
|
query,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
}) {
|
||||||
|
return Instance.call(this).requestListLookupFromReference({
|
||||||
tableName,
|
tableName,
|
||||||
query
|
query,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,26 +198,27 @@ export function runProcess({ uuid, reportType, tableName, recordId, parameters:
|
||||||
* value
|
* value
|
||||||
* }]
|
* }]
|
||||||
*/
|
*/
|
||||||
export function getBrowserSearch({ uuid, parameters: parametersList = [], query, whereClause, orderByClause, nextPageToken }) {
|
export function getBrowserSearch({ uuid, parameters: parametersList = [], query, whereClause, orderByClause, nextPageToken: pageToken, pageSize }) {
|
||||||
// Run browser
|
// Run browser
|
||||||
return Instance.call(this).requestBrowserSearch({
|
return Instance.call(this).requestListBrowserSearch({
|
||||||
uuid,
|
uuid,
|
||||||
parametersList,
|
parametersList,
|
||||||
query,
|
query,
|
||||||
whereClause,
|
whereClause,
|
||||||
orderByClause,
|
orderByClause,
|
||||||
nextPageToken
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request a Process Activity list
|
// Request a Process Activity list
|
||||||
export function requestProcessActivity() {
|
export function requestProcessActivity({ pageToken, pageSize }) {
|
||||||
// Get Process Activity
|
// Get Process Activity
|
||||||
return Instance.call(this).requestProcessActivity()
|
return Instance.call(this).requestListProcessesLogs({ pageToken, pageSize })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRecentItems() {
|
export function getRecentItems({ pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestRecentItems()
|
return Instance.call(this).requestListRecentItems({ pageToken, pageSize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,12 +228,14 @@ export function getRecentItems() {
|
||||||
* @param {string} recordUuid
|
* @param {string} recordUuid
|
||||||
* @param {number} recordId
|
* @param {number} recordId
|
||||||
*/
|
*/
|
||||||
export function getReferencesList({ windowUuid, tableName, recordId, recordUuid }) {
|
export function getReferencesList({ windowUuid, tableName, recordId, recordUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).listReferencesRequest({
|
return Instance.call(this).requestListReferences({
|
||||||
windowUuid,
|
windowUuid,
|
||||||
tableName,
|
tableName,
|
||||||
recordId,
|
recordId,
|
||||||
recordUuid
|
recordUuid,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,14 +302,16 @@ export function unlockPrivateAccessFromServer({ tableName, recordId, userUuid })
|
||||||
* Request Favorites List
|
* Request Favorites List
|
||||||
* @param {string} userUuid
|
* @param {string} userUuid
|
||||||
*/
|
*/
|
||||||
export function getFavoritesFromServer(userUuid) {
|
export function getFavoritesFromServer({ userUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestFavorites(userUuid)
|
return Instance.call(this).requestListFavorites({ userUuid, pageToken, pageSize })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPendingDocumentsFromServer({ userUuid, roleUuid }) {
|
export function getPendingDocumentsFromServer({ userUuid, roleUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestPendingDocuments({
|
return Instance.call(this).requestListPendingDocuments({
|
||||||
userUuid,
|
userUuid,
|
||||||
roleUuid
|
roleUuid,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,27 +320,35 @@ export function getPendingDocumentsFromServer({ userUuid, roleUuid }) {
|
||||||
* @param {string} tableName
|
* @param {string} tableName
|
||||||
* @param {string} processUuid
|
* @param {string} processUuid
|
||||||
*/
|
*/
|
||||||
export function requestReportViews({ tableName, processUuid }) {
|
export function requestReportViews({ tableName, processUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestReportViews({
|
return Instance.call(this).requestListReportViews({
|
||||||
tableName,
|
tableName,
|
||||||
processUuid
|
processUuid,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestPrintFormats({ tableName, reportViewUuid, processUuid }) {
|
export function requestPrintFormats({ tableName, reportViewUuid, processUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestPrintFormats({
|
return Instance.call(this).requestListPrintFormats({
|
||||||
tableName,
|
tableName,
|
||||||
reportViewUuid,
|
reportViewUuid,
|
||||||
processUuid
|
processUuid,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestLisDashboards(roleUuid) {
|
export function requestLisDashboards({ roleUuid, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestDashboards(roleUuid)
|
return Instance.call(this).requestListDashboards({
|
||||||
|
roleUuid,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestLanguages() {
|
export function requestLanguages({ pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestLanguages()
|
return Instance.call(this).requestListLanguages({ pageToken, pageSize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -321,17 +358,23 @@ export function requestLanguages() {
|
||||||
* @param {string} recordUuid
|
* @param {string} recordUuid
|
||||||
* @param {integer} recordId
|
* @param {integer} recordId
|
||||||
*/
|
*/
|
||||||
export function requestTranslations({ tableName, language, recordUuid, recordId }) {
|
export function requestTranslations({ tableName, language, recordUuid, recordId, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestTranslations({
|
return Instance.call(this).requestTranslations({
|
||||||
tableName,
|
tableName,
|
||||||
recordUuid,
|
recordUuid,
|
||||||
recordId,
|
recordId,
|
||||||
language
|
language,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestDrillTables(tableName) {
|
export function requestDrillTables({ tableName, pageToken, pageSize }) {
|
||||||
return Instance.call(this).requestDrillTables(tableName)
|
return Instance.call(this).requestListDrillTables({
|
||||||
|
tableName,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getReportOutput({
|
export function getReportOutput({
|
||||||
|
@ -353,3 +396,31 @@ export function getReportOutput({
|
||||||
reportType
|
reportType
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function requestListRecordsLogs({
|
||||||
|
tableName,
|
||||||
|
recordId,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
}) {
|
||||||
|
return Instance.call(this).requestListRecordsLogs({
|
||||||
|
tableName,
|
||||||
|
recordId,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requestListWorkflowsLogs({
|
||||||
|
tableName,
|
||||||
|
recordId,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
}) {
|
||||||
|
return Instance.call(this).requestListWorkflowsLogs({
|
||||||
|
tableName,
|
||||||
|
recordId,
|
||||||
|
pageToken,
|
||||||
|
pageSize
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
// Export dictionary connection
|
// Export dictionary connection
|
||||||
export * from './dictionary'
|
export * from './dictionary'
|
||||||
|
|
||||||
// Export data connection
|
// Export data connection
|
||||||
export * from './data'
|
export * from './data'
|
||||||
|
|
||||||
|
// Export enrollment user connection
|
||||||
|
export * from './enrollment'
|
||||||
|
|
|
@ -62,7 +62,7 @@ export default {
|
||||||
getFavoritesList() {
|
getFavoritesList() {
|
||||||
const userUuid = this.$store.getters['user/getUserUuid']
|
const userUuid = this.$store.getters['user/getUserUuid']
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getFavoritesFromServer(userUuid)
|
getFavoritesFromServer({ userUuid })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
const favorites = response.favoritesList.map(favoriteElement => {
|
const favorites = response.favoritesList.map(favoriteElement => {
|
||||||
const actionConverted = convertAction(favoriteElement.action)
|
const actionConverted = convertAction(favoriteElement.action)
|
||||||
|
|
|
@ -59,16 +59,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getRecentItems()
|
this.getRecentItems({ pageToken: undefined, pageSize: undefined })
|
||||||
this.subscribeChanges()
|
this.subscribeChanges()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkOpened(uuid) {
|
checkOpened(uuid) {
|
||||||
return this.cachedViews.includes(uuid)
|
return this.cachedViews.includes(uuid)
|
||||||
},
|
},
|
||||||
getRecentItems() {
|
getRecentItems({ pageToken, pageSize }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getRecentItemsFromServer()
|
getRecentItemsFromServer({ pageToken, pageSize })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
const recentItems = response.recentItemsList.map(item => {
|
const recentItems = response.recentItemsList.map(item => {
|
||||||
const actionConverted = convertAction(item.action)
|
const actionConverted = convertAction(item.action)
|
||||||
|
|
|
@ -150,7 +150,7 @@ export default {
|
||||||
const selection = this.$store.getters.getProcessSelect
|
const selection = this.$store.getters.getProcessSelect
|
||||||
if (porcesTabla) {
|
if (porcesTabla) {
|
||||||
// selection.forEach(element => {
|
// selection.forEach(element => {
|
||||||
this.$store.dispatch('SelectionProcess', {
|
this.$store.dispatch('selectionProcess', {
|
||||||
action: action, // process metadata
|
action: action, // process metadata
|
||||||
parentUuid: this.parentUuid,
|
parentUuid: this.parentUuid,
|
||||||
containerUuid: this.containerUuid,
|
containerUuid: this.containerUuid,
|
||||||
|
|
|
@ -24,7 +24,7 @@ const dashboard = {
|
||||||
},
|
},
|
||||||
listDashboard({ commit }, roleUuid) {
|
listDashboard({ commit }, roleUuid) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
requestLisDashboards(roleUuid)
|
requestLisDashboards({ roleUuid })
|
||||||
.then(dashboardResponse => {
|
.then(dashboardResponse => {
|
||||||
const roleDashboards = {
|
const roleDashboards = {
|
||||||
roleUuid: roleUuid,
|
roleUuid: roleUuid,
|
||||||
|
@ -40,7 +40,7 @@ const dashboard = {
|
||||||
},
|
},
|
||||||
getRecentItemsFromServer({ commit }) {
|
getRecentItemsFromServer({ commit }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getRecentItems()
|
getRecentItems({ pageToken: undefined, pageSize: undefined })
|
||||||
.then(recentItemsResponse => {
|
.then(recentItemsResponse => {
|
||||||
const recentItems = recentItemsResponse.recentItemsList.map(item => {
|
const recentItems = recentItemsResponse.recentItemsList.map(item => {
|
||||||
const actionConverted = convertAction(item.action)
|
const actionConverted = convertAction(item.action)
|
||||||
|
@ -55,7 +55,7 @@ const dashboard = {
|
||||||
resolve(recentItems)
|
resolve(recentItems)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.warn(`Error gettin recent items: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error gettin recent items: ${error.message}. Code: ${error.code}.`)
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -30,7 +30,7 @@ const languageControl = {
|
||||||
actions: {
|
actions: {
|
||||||
getLanguagesFromServer({ commit }) {
|
getLanguagesFromServer({ commit }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
requestLanguages()
|
requestLanguages({ pageToke: undefined, pageSize: undefined })
|
||||||
.then(languageResponse => {
|
.then(languageResponse => {
|
||||||
commit('setlanguagesList', languageResponse.languagesList)
|
commit('setlanguagesList', languageResponse.languagesList)
|
||||||
resolve(languageResponse.languagesList)
|
resolve(languageResponse.languagesList)
|
||||||
|
|
|
@ -553,7 +553,7 @@ const processControl = {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
isProcessing: false
|
isProcessing: false
|
||||||
})
|
})
|
||||||
console.warn(`Error running the process ${error.message}. Code: ${error.code}`)
|
console.warn(`Error running the process ${error.message}. Code: ${error.code}.`)
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -597,7 +597,7 @@ const processControl = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// Supported to process selection
|
// Supported to process selection
|
||||||
SelectionProcess({ commit, state, dispatch, getters, rootGetters }, params) {
|
selectionProcess({ commit, state, dispatch, getters, rootGetters }, params) {
|
||||||
// get info metadata process
|
// get info metadata process
|
||||||
const processDefinition = rootGetters.getProcess(params.action.uuid)
|
const processDefinition = rootGetters.getProcess(params.action.uuid)
|
||||||
var reportType = 'pdf'
|
var reportType = 'pdf'
|
||||||
|
@ -785,7 +785,7 @@ const processControl = {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
isProcessing: false
|
isProcessing: false
|
||||||
})
|
})
|
||||||
console.warn(`Error running the process ${error}`)
|
console.warn(`Error running the process ${error}.`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -798,7 +798,7 @@ const processControl = {
|
||||||
// process Activity
|
// process Activity
|
||||||
return requestProcessActivity()
|
return requestProcessActivity()
|
||||||
.then(processActivityResponse => {
|
.then(processActivityResponse => {
|
||||||
const responseList = processActivityResponse.responsesList.map(businessProcessItem => {
|
const responseList = processActivityResponse.processLogsList.map(businessProcessItem => {
|
||||||
const processMetadata = rootGetters.getProcess(businessProcessItem.uuid)
|
const processMetadata = rootGetters.getProcess(businessProcessItem.uuid)
|
||||||
// if no exists metadata process in store and no request progess
|
// if no exists metadata process in store and no request progess
|
||||||
if (processMetadata === undefined && getters.getInRequestMetadata(businessProcessItem.uuid) === undefined) {
|
if (processMetadata === undefined && getters.getInRequestMetadata(businessProcessItem.uuid) === undefined) {
|
||||||
|
@ -832,7 +832,7 @@ const processControl = {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
console.warn(`Error getting process activity: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error getting process activity: ${error.message}. Code: ${error.code}.`)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -46,7 +46,7 @@ const contextMenu = {
|
||||||
return printFormatList
|
return printFormatList
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.warn(`Error getting print formats: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error getting print formats: ${error.message}. Code: ${error.code}.`)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
requestReportViews({ commit }, {
|
requestReportViews({ commit }, {
|
||||||
|
@ -75,7 +75,7 @@ const contextMenu = {
|
||||||
return reportViewList
|
return reportViewList
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.warn(`Error getting report views: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error getting report views: ${error.message}. Code: ${error.code}.`)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
requestDrillTables({ commit }, {
|
requestDrillTables({ commit }, {
|
||||||
|
@ -86,7 +86,7 @@ const contextMenu = {
|
||||||
tableName,
|
tableName,
|
||||||
reportViewUuid
|
reportViewUuid
|
||||||
}) {
|
}) {
|
||||||
return requestDrillTables(tableName)
|
return requestDrillTables({ tableName })
|
||||||
.then(responseDrillTables => {
|
.then(responseDrillTables => {
|
||||||
const drillTablesList = responseDrillTables.drillTablesList.map(drillTableItem => {
|
const drillTablesList = responseDrillTables.drillTablesList.map(drillTableItem => {
|
||||||
return {
|
return {
|
||||||
|
@ -108,7 +108,7 @@ const contextMenu = {
|
||||||
return drillTablesList
|
return drillTablesList
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.warn(`Error getting drill tables: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error getting drill tables: ${error.message}. Code: ${error.code}.`)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getReportOutputFromServer({ commit, getters, rootGetters }, parameters) {
|
getReportOutputFromServer({ commit, getters, rootGetters }, parameters) {
|
||||||
|
@ -174,7 +174,7 @@ const contextMenu = {
|
||||||
isReport: true,
|
isReport: true,
|
||||||
option: ''
|
option: ''
|
||||||
}
|
}
|
||||||
console.warn(`Error getting report output: ${error.message}. Code: ${error.code}`)
|
console.warn(`Error getting report output: ${error.message}. Code: ${error.code}.`)
|
||||||
return reportOutput
|
return reportOutput
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue