\n\n \n \n {{ $t('words.collapse') }}\n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n\n\n\n\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Card.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Card.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Card.vue?vue&type=template&id=1fe12dfc&scoped=true&\"\nimport script from \"./Card.vue?vue&type=script&lang=js&\"\nexport * from \"./Card.vue?vue&type=script&lang=js&\"\nimport style0 from \"./Card.vue?vue&type=style&index=0&id=1fe12dfc&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"1fe12dfc\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('b-button',{staticClass:\"d-block mb-3\",attrs:{\"id\":_vm.id,\"variant\":_vm.type,\"disabled\":!_vm.enabled},on:{\"click\":function($event){return _vm.$emit('action', $event)}}},[_c('icon',{staticClass:\"mr-2\",attrs:{\"iname\":_vm.icon_}}),_c('span',{domProps:{\"innerHTML\":_vm._s(_vm.label)}})],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n \n \n \n \n\n\n\n","import mod from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ButtonItem.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ButtonItem.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./ButtonItem.vue?vue&type=template&id=53ec2cfc&\"\nimport script from \"./ButtonItem.vue?vue&type=script&lang=js&\"\nexport * from \"./ButtonItem.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./MessageListGroup.vue?vue&type=style&index=0&id=78fe801e&lang=scss&scoped=true&\"","/**\n * API errors definitionss.\n * @module api/errors\n */\n\nimport i18n from '@/i18n'\n\n\nclass APIError extends Error {\n constructor (request, { url, status, statusText }, { error }) {\n super(error ? error.replaceAll('\\n', ' ') : i18n.t('error_server_unexpected'))\n const urlObj = new URL(url)\n this.name = 'APIError'\n this.code = status\n this.status = statusText\n this.method = request.method\n this.request = request\n this.path = urlObj.pathname + urlObj.search\n }\n\n log () {\n /* eslint-disable-next-line */\n console.error(`${this.name} (${this.code}): ${this.uri}\\n${this.message}`)\n }\n}\n\n// Log (Special error to trigger a redirect to a log page)\nclass APIErrorLog extends APIError {\n constructor (method, response, errorData) {\n super(method, response, errorData)\n this.logRef = errorData.log_ref\n this.name = 'APIErrorLog'\n }\n}\n\n\n// 0 — (means \"the connexion has been closed\" apparently)\nclass APIConnexionError extends APIError {\n constructor (method, response) {\n super(method, response, { error: i18n.t('error_connection_interrupted') })\n this.name = 'APIConnexionError'\n }\n}\n\n\n// 400 — Bad Request\nclass APIBadRequestError extends APIError {\n constructor (method, response, errorData) {\n super(method, response, errorData)\n this.name = 'APIBadRequestError'\n this.key = errorData.error_key\n this.data = errorData\n }\n}\n\n\n// 401 — Unauthorized\nclass APIUnauthorizedError extends APIError {\n constructor (method, response, errorData) {\n super(method, response, { error: i18n.t('unauthorized') })\n this.name = 'APIUnauthorizedError'\n }\n}\n\n\n// 404 — Not Found\nclass APINotFoundError extends APIError {\n constructor (method, response, errorData) {\n errorData.error = i18n.t('api_not_found')\n super(method, response, errorData)\n this.name = 'APINotFoundError'\n }\n}\n\n\n// 500 — Server Internal Error\nclass APIInternalError extends APIError {\n constructor (method, response, errorData) {\n super(method, response, errorData)\n this.traceback = errorData.traceback || null\n this.name = 'APIInternalError'\n }\n}\n\n\n// 502 — Bad gateway (means API is down)\nclass APINotRespondingError extends APIError {\n constructor (method, response) {\n super(method, response, { error: i18n.t('api_not_responding') })\n this.name = 'APINotRespondingError'\n }\n}\n\n\n// Temp factory\nconst errors = {\n [undefined]: APIError,\n log: APIErrorLog,\n 0: APIConnexionError,\n 400: APIBadRequestError,\n 401: APIUnauthorizedError,\n 404: APINotFoundError,\n 500: APIInternalError,\n 502: APINotRespondingError\n}\n\n\nexport {\n errors as default,\n APIError,\n APIErrorLog,\n APIBadRequestError,\n APIConnexionError,\n APIInternalError,\n APINotFoundError,\n APINotRespondingError,\n APIUnauthorizedError\n}\n","/**\n * API handlers.\n * @module api/handlers\n */\n\nimport store from '@/store'\nimport errors, { APIError } from './errors'\n\n\n/**\n * Try to get response content as json and if it's not as text.\n *\n * @param {Response} response - A fetch `Response` object.\n * @return {(Object|String)} Parsed response's json or response's text.\n */\nexport async function getResponseData (response) {\n // FIXME the api should always return json as response\n const responseText = await response.text()\n try {\n return JSON.parse(responseText)\n } catch {\n return responseText\n }\n}\n\n\n/**\n * Opens a WebSocket connection to the server in case it sends messages.\n * Currently, the connection is closed by the server right after an API call so\n * we have to open it for every calls.\n * Messages are dispatch to the store so it can handle them.\n *\n * @param {Object} request - Request info data.\n * @return {Promise} Promise that resolve on websocket 'open' or 'error' event.\n */\nexport function openWebSocket (request) {\n return new Promise(resolve => {\n const ws = new WebSocket(`wss://${store.getters.host}/yunohost/api/messages`)\n ws.onmessage = ({ data }) => {\n store.dispatch('DISPATCH_MESSAGE', { request, messages: JSON.parse(data) })\n }\n // ws.onclose = (e) => {}\n ws.onopen = resolve\n // Resolve also on error so the actual fetch may be called.\n ws.onerror = resolve\n })\n}\n\n\n/**\n * Handler for API errors.\n *\n * @param {Object} request - Request info data.\n * @param {Response} response - A consumed fetch `Response` object.\n * @param {Object|String} errorData - The response parsed json/text.\n * @throws Will throw a `APIError` with request and response data.\n */\nexport async function handleError (request, response, errorData) {\n let errorCode = response.status in errors ? response.status : undefined\n if (typeof errorData === 'string') {\n // FIXME API: Patching errors that are plain text or html.\n errorData = { error: errorData }\n }\n if ('log_ref' in errorData) {\n // Define a special error so it won't get caught as a `APIBadRequestError`.\n errorCode = 'log'\n }\n\n // This error can be catched by a view otherwise it will be catched by the `onUnhandledAPIError` handler.\n throw new errors[errorCode](request, response, errorData)\n}\n\n\n/**\n * If an APIError is not catched by a view it will be dispatched to the store so the\n * error can be displayed in the error modal.\n *\n * @param {APIError} error\n */\nexport function onUnhandledAPIError (error) {\n // In 'development', Babel seems to also catch the error so there's no need to log it twice.\n if (process.env.NODE_ENV !== 'development') {\n error.log()\n }\n store.dispatch('HANDLE_ERROR', error)\n}\n\n\n/**\n * Global catching of unhandled promise's rejections.\n * Those errors (thrown or rejected from inside a promise) can't be catched by\n * `window.onerror`.\n */\nexport function registerGlobalErrorHandlers () {\n window.addEventListener('unhandledrejection', e => {\n const error = e.reason\n if (error instanceof APIError) {\n onUnhandledAPIError(error)\n // Seems like there's a bug in Firefox and the error logging in not prevented.\n e.preventDefault()\n }\n })\n\n // Keeping this in case it is needed.\n\n // Global catching of errors occuring inside vue components.\n // Vue.config.errorHandler = (err, vm, info) => {}\n\n // Global catching of regular js errors.\n // window.onerror = (message, source, lineno, colno, error) => {}\n}\n","/**\n * API module.\n * @module api\n */\n\nimport store from '@/store'\nimport { openWebSocket, getResponseData, handleError } from './handlers'\n\n\n/**\n * Options available for an API call.\n *\n * @typedef {Object} Options\n * @property {Boolean} wait - If `true`, will display the waiting modal.\n * @property {Boolean} websocket - if `true`, will open a websocket connection.\n * @property {Boolean} initial - if `true` and an error occurs, the dismiss button will trigger a go back in history.\n * @property {Boolean} asFormData - if `true`, will send the data with a body encoded as `\"multipart/form-data\"` instead of `\"x-www-form-urlencoded\"`).\n */\n\n\n/**\n * Representation of an API call for `api.fetchAll`\n *\n * @typedef {Array} Query\n * @property {String} 0 - \"method\"\n * @property {String|Object} 1 - \"uri\", uri to call as string or as an object for cached uris.\n * @property {Object|null} 2 - \"data\"\n * @property {Options} 3 - \"options\"\n*/\n\n\n/**\n * Converts an object literal into an `URLSearchParams` that can be turned into a\n * query string or used as a body in a `fetch` call.\n *\n * @param {Object} obj - An object literal to convert.\n * @param {Object} options\n * @param {Boolean} [options.addLocale=false] - Option to append the locale to the query string.\n * @return {URLSearchParams}\n */\nexport function objectToParams (obj, { addLocale = false } = {}, formData = false) {\n const urlParams = (formData) ? new FormData() : new URLSearchParams()\n for (const [key, value] of Object.entries(obj)) {\n if (Array.isArray(value)) {\n value.forEach(v => urlParams.append(key, v))\n } else {\n urlParams.append(key, value)\n }\n }\n if (addLocale) {\n urlParams.append('locale', store.getters.locale)\n }\n return urlParams\n}\n\n\nexport default {\n options: {\n credentials: 'include',\n mode: 'cors',\n headers: {\n // FIXME is it important to keep this previous `Accept` header ?\n // 'Accept': 'application/json, text/javascript, */*; q=0.01',\n // Auto header is :\n // \"Accept\": \"*/*\",\n\n 'X-Requested-With': 'XMLHttpRequest'\n }\n },\n\n\n /**\n * Generic method to fetch the api without automatic response handling.\n *\n * @param {String} method - a method between 'GET', 'POST', 'PUT' and 'DELETE'.\n * @param {String} uri\n * @param {Object} [data={}] - data to send as body.\n * @param {Options} [options={ wait = true, websocket = true, initial = false, asFormData = false }]\n * @return {Promise