Merge pull request #245 from jat255/add_date_formats

Add ability to customize format used to display dates throughout the app
This commit is contained in:
Sam 2022-11-01 14:46:02 +01:00 committed by GitHub
commit c4bb41caf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 490 additions and 82 deletions

View File

@ -42,6 +42,9 @@ clean-install: clean
rm -rf dist/
## Docker commands for evaluation purposes
docker-bandit:
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_BANDIT) -r fittrackee -c pyproject.toml
docker-build:
docker-compose -f docker-compose-dev.yml build fittrackee
@ -50,11 +53,15 @@ docker-build-all: docker-build docker-build-client
docker-build-client:
docker-compose -f docker-compose-dev.yml build fittrackee_client
docker-check-all: docker-bandit docker-lint-all docker-type-check docker-test-client docker-test-python
docker-init: docker-run docker-init-db docker-restart docker-run-workers
docker-init-db:
docker-compose -f docker-compose-dev.yml exec fittrackee docker/init-database.sh
docker-lint-all: docker-lint-client docker-lint-python
docker-lint-client:
docker-compose -f docker-compose-dev.yml up -d fittrackee_client
docker-compose -f docker-compose-dev.yml exec fittrackee_client yarn lint
@ -65,12 +72,18 @@ docker-lint-python: docker-run
docker-logs:
docker-compose -f docker-compose-dev.yml logs --follow
docker-migrate-db:
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_FLASK) db migrate --directory $(DOCKER_MIGRATIONS)
docker-rebuild:
docker-compose -f docker-compose-dev.yml build --no-cache
docker-restart:
docker-compose -f docker-compose-dev.yml restart fittrackee
docker-revision:
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_FLASK) db revision --directory $(DOCKER_MIGRATIONS) --message $(MIGRATION_MESSAGE)
docker-run-all: docker-run docker-run-workers
docker-run:
@ -104,9 +117,16 @@ docker-test-e2e: docker-run
docker-test-python: docker-run
docker-compose -f docker-compose-dev.yml exec fittrackee docker/test-python.sh $(PYTEST_ARGS)
docker-type-check:
echo 'Running mypy in docker...'
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_MYPY) fittrackee
docker-up:
docker-compose -f docker-compose-dev.yml up fittrackee
docker-upgrade-db:
docker-compose -f docker-compose-dev.yml exec fittrackee $(DOCKER_FTCLI) db upgrade
downgrade-db:
$(FLASK) db downgrade --directory $(MIGRATIONS)

View File

@ -27,6 +27,14 @@ BANDIT = $(VENV)/bin/bandit
PYBABEL = $(VENV)/bin/pybabel
FTCLI = $(VENV)/bin/ftcli
# Docker env
export DOCKER_APP_DIR = /usr/src/app
export DOCKER_MIGRATIONS = $(DOCKER_APP_DIR)/fittrackee/migrations
export DOCKER_FLASK = /usr/local/bin/flask
export DOCKER_FTCLI = /usr/local/bin/ftcli
export DOCKER_BANDIT = /usr/local/bin/bandit
export DOCKER_MYPY = /usr/local/bin/mypy
# Node env
NODE_MODULES = $(PWD)/fittrackee_client/node_modules
NPM ?= yarn

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.e9c5b3a5.js"></script><script defer="defer" src="/static/js/app.f492102f.js"></script><link href="/static/css/app.eee1934d.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"/><link rel="stylesheet" href="/static/css/leaflet.css"/><title>FitTrackee</title><script defer="defer" src="/static/js/chunk-vendors.a306e708.js"></script><script defer="defer" src="/static/js/app.2c35ea55.js"></script><link href="/static/css/app.a67ca8d9.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[328],{6e3:function(t,e,i){i.r(e),i.d(e,{default:function(){return _}});var a=i(6252),n=i(2262),s=i(8273),c=i(5801),r=i(9917);const S=t=>((0,a.dD)("data-v-64629971"),t=t(),(0,a.Cn)(),t),l={id:"admin",class:"view"},p={key:0,class:"container"},u=S((()=>(0,a._)("div",{id:"bottom"},null,-1)));var T=(0,a.aZ)({__name:"AdminView",setup(t){const e=(0,r.o)(),i=(0,a.Fl)((()=>e.getters[c.SY.GETTERS.APP_CONFIG])),S=(0,a.Fl)((()=>e.getters[c.SY.GETTERS.APP_STATS])),T=(0,a.Fl)((()=>e.getters[c.YN.GETTERS.IS_ADMIN])),d=(0,a.Fl)((()=>e.getters[c.YN.GETTERS.USER_LOADING]));return(0,a.wF)((()=>e.dispatch(c.SY.ACTIONS.GET_APPLICATION_STATS))),(t,e)=>{const c=(0,a.up)("router-view");return(0,a.wg)(),(0,a.iD)("div",l,[(0,n.SU)(d)?(0,a.kq)("",!0):((0,a.wg)(),(0,a.iD)("div",p,[(0,n.SU)(T)?((0,a.wg)(),(0,a.j4)(c,{key:0,appConfig:(0,n.SU)(i),appStatistics:(0,n.SU)(S)},null,8,["appConfig","appStatistics"])):((0,a.wg)(),(0,a.j4)(s.Z,{key:1})),u]))])}}}),d=i(3744);const o=(0,d.Z)(T,[["__scopeId","data-v-64629971"]]);var _=o}}]);
//# sourceMappingURL=admin.ab9e5f5f.js.map
//# sourceMappingURL=admin.3b0b84c0.js.map

View File

@ -1 +1 @@
{"version":3,"file":"static/js/admin.ab9e5f5f.js","mappings":"mOAGA,MAAMA,EAAeC,KAAMC,EAAAA,EAAAA,IAAa,mBAAmBD,EAAEA,KAAIE,EAAAA,EAAAA,MAAcF,GACzEG,EAAa,CACjBC,GAAI,QACJC,MAAO,QAEHC,EAAa,CACjBC,IAAK,EACLF,MAAO,aAEHG,EAA2BT,GAAa,KAAmBU,EAAAA,EAAAA,GAAoB,MAAO,CAAEL,GAAI,UAAY,MAAO,KAUrH,OAA4BM,EAAAA,EAAAA,IAAiB,CAC3CC,OAAQ,YACRC,MAAMC,GAEN,MAAMC,GAAQC,EAAAA,EAAAA,KAERC,GAAqCC,EAAAA,EAAAA,KACzC,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,cAEhBC,GAA6CH,EAAAA,EAAAA,KACjD,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,aAEhBE,GAAuCJ,EAAAA,EAAAA,KAC3C,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,YAEhBC,GAAoCN,EAAAA,EAAAA,KACxC,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,gBAKxB,OAFEE,EAAAA,EAAAA,KAAc,IAAMV,EAAMW,SAASN,EAAAA,GAAAA,QAAAA,yBAE9B,CAACO,EAAUC,KAChB,MAAMC,GAAyBC,EAAAA,EAAAA,IAAkB,eAEjD,OAAQC,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAO5B,EAAY,EACzD6B,EAAAA,EAAAA,IAAOT,IAWLU,EAAAA,EAAAA,IAAoB,IAAI,KAVvBH,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAOzB,EAAY,EACnD0B,EAAAA,EAAAA,IAAOX,KACHS,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaN,EAAwB,CAClDrB,IAAK,EACLS,WAAWgB,EAAAA,EAAAA,IAAOhB,GAClBI,eAAeY,EAAAA,EAAAA,IAAOZ,IACrB,KAAM,EAAG,CAAC,YAAa,qBACzBU,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaC,EAAAA,EAAU,CAAE5B,IAAK,KACjDC,MAVR,CAeD,I,UCvDD,MAAM4B,GAA2B,OAAgB,EAAQ,CAAC,CAAC,YAAY,qBAEvE,O","sources":["webpack://fittrackee_client/./src/views/AdminView.vue?67de","webpack://fittrackee_client/./src/views/AdminView.vue"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createElementVNode as _createElementVNode, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-64629971\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n id: \"admin\",\n class: \"view\"\n}\nconst _hoisted_2 = {\n key: 0,\n class: \"container\"\n}\nconst _hoisted_3 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"div\", { id: \"bottom\" }, null, -1))\n\nimport { computed, ComputedRef, onBeforeMount } from 'vue'\n\n import NotFound from '@/components/Common/NotFound.vue'\n import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'\n import { TAppConfig, IAppStatistics } from '@/types/application'\n import { useStore } from '@/use/useStore'\n\n \nexport default /*#__PURE__*/_defineComponent({\n __name: 'AdminView',\n setup(__props) {\n\n const store = useStore()\n\n const appConfig: ComputedRef<TAppConfig> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]\n )\n const appStatistics: ComputedRef<IAppStatistics> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_STATS]\n )\n const isAuthUserAmin: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.IS_ADMIN]\n )\n const userLoading: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]\n )\n\n onBeforeMount(() => store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_STATS))\n\nreturn (_ctx: any,_cache: any) => {\n const _component_router_view = _resolveComponent(\"router-view\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (!_unref(userLoading))\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_2, [\n (_unref(isAuthUserAmin))\n ? (_openBlock(), _createBlock(_component_router_view, {\n key: 0,\n appConfig: _unref(appConfig),\n appStatistics: _unref(appStatistics)\n }, null, 8, [\"appConfig\", \"appStatistics\"]))\n : (_openBlock(), _createBlock(NotFound, { key: 1 })),\n _hoisted_3\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n}\n}\n\n})","import script from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\nexport * from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\n\nimport \"./AdminView.vue?vue&type=style&index=0&id=64629971&lang=scss&scoped=true\"\n\nimport exportComponent from \"/mnt/data-lnx/Devs/00_Perso/FitTrackee/fittrackee_client/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-64629971\"]])\n\nexport default __exports__"],"names":["_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_1","id","class","_hoisted_2","key","_hoisted_3","_createElementVNode","_defineComponent","__name","setup","__props","store","useStore","appConfig","computed","getters","ROOT_STORE","appStatistics","isAuthUserAmin","AUTH_USER_STORE","userLoading","onBeforeMount","dispatch","_ctx","_cache","_component_router_view","_resolveComponent","_openBlock","_createElementBlock","_unref","_createCommentVNode","_createBlock","NotFound","__exports__"],"sourceRoot":""}
{"version":3,"file":"static/js/admin.3b0b84c0.js","mappings":"mOAGA,MAAMA,EAAeC,KAAMC,EAAAA,EAAAA,IAAa,mBAAmBD,EAAEA,KAAIE,EAAAA,EAAAA,MAAcF,GACzEG,EAAa,CACjBC,GAAI,QACJC,MAAO,QAEHC,EAAa,CACjBC,IAAK,EACLF,MAAO,aAEHG,EAA2BT,GAAa,KAAmBU,EAAAA,EAAAA,GAAoB,MAAO,CAAEL,GAAI,UAAY,MAAO,KAUrH,OAA4BM,EAAAA,EAAAA,IAAiB,CAC3CC,OAAQ,YACRC,MAAMC,GAEN,MAAMC,GAAQC,EAAAA,EAAAA,KAERC,GAAqCC,EAAAA,EAAAA,KACzC,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,cAEhBC,GAA6CH,EAAAA,EAAAA,KACjD,IAAMH,EAAMI,QAAQC,EAAAA,GAAAA,QAAAA,aAEhBE,GAAuCJ,EAAAA,EAAAA,KAC3C,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,YAEhBC,GAAoCN,EAAAA,EAAAA,KACxC,IAAMH,EAAMI,QAAQI,EAAAA,GAAAA,QAAAA,gBAKxB,OAFEE,EAAAA,EAAAA,KAAc,IAAMV,EAAMW,SAASN,EAAAA,GAAAA,QAAAA,yBAE9B,CAACO,EAAUC,KAChB,MAAMC,GAAyBC,EAAAA,EAAAA,IAAkB,eAEjD,OAAQC,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAO5B,EAAY,EACzD6B,EAAAA,EAAAA,IAAOT,IAWLU,EAAAA,EAAAA,IAAoB,IAAI,KAVvBH,EAAAA,EAAAA,OAAcC,EAAAA,EAAAA,IAAoB,MAAOzB,EAAY,EACnD0B,EAAAA,EAAAA,IAAOX,KACHS,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaN,EAAwB,CAClDrB,IAAK,EACLS,WAAWgB,EAAAA,EAAAA,IAAOhB,GAClBI,eAAeY,EAAAA,EAAAA,IAAOZ,IACrB,KAAM,EAAG,CAAC,YAAa,qBACzBU,EAAAA,EAAAA,OAAcI,EAAAA,EAAAA,IAAaC,EAAAA,EAAU,CAAE5B,IAAK,KACjDC,MAVR,CAeD,I,UCvDD,MAAM4B,GAA2B,OAAgB,EAAQ,CAAC,CAAC,YAAY,qBAEvE,O","sources":["webpack://fittrackee_client/./src/views/AdminView.vue?67de","webpack://fittrackee_client/./src/views/AdminView.vue"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createElementVNode as _createElementVNode, createElementBlock as _createElementBlock, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \"vue\"\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-64629971\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = {\n id: \"admin\",\n class: \"view\"\n}\nconst _hoisted_2 = {\n key: 0,\n class: \"container\"\n}\nconst _hoisted_3 = /*#__PURE__*/ _withScopeId(() => /*#__PURE__*/_createElementVNode(\"div\", { id: \"bottom\" }, null, -1))\n\nimport { computed, ComputedRef, onBeforeMount } from 'vue'\n\n import NotFound from '@/components/Common/NotFound.vue'\n import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'\n import { TAppConfig, IAppStatistics } from '@/types/application'\n import { useStore } from '@/use/useStore'\n\n \nexport default /*#__PURE__*/_defineComponent({\n __name: 'AdminView',\n setup(__props) {\n\n const store = useStore()\n\n const appConfig: ComputedRef<TAppConfig> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]\n )\n const appStatistics: ComputedRef<IAppStatistics> = computed(\n () => store.getters[ROOT_STORE.GETTERS.APP_STATS]\n )\n const isAuthUserAmin: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.IS_ADMIN]\n )\n const userLoading: ComputedRef<boolean> = computed(\n () => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]\n )\n\n onBeforeMount(() => store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_STATS))\n\nreturn (_ctx: any,_cache: any) => {\n const _component_router_view = _resolveComponent(\"router-view\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (!_unref(userLoading))\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_2, [\n (_unref(isAuthUserAmin))\n ? (_openBlock(), _createBlock(_component_router_view, {\n key: 0,\n appConfig: _unref(appConfig),\n appStatistics: _unref(appStatistics)\n }, null, 8, [\"appConfig\", \"appStatistics\"]))\n : (_openBlock(), _createBlock(NotFound, { key: 1 })),\n _hoisted_3\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n}\n}\n\n})","import script from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\nexport * from \"./AdminView.vue?vue&type=script&setup=true&lang=ts\"\n\nimport \"./AdminView.vue?vue&type=style&index=0&id=64629971&lang=scss&scoped=true\"\n\nimport exportComponent from \"/mnt/data-lnx/Devs/00_Perso/FitTrackee/fittrackee_client/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['__scopeId',\"data-v-64629971\"]])\n\nexport default __exports__"],"names":["_withScopeId","n","_pushScopeId","_popScopeId","_hoisted_1","id","class","_hoisted_2","key","_hoisted_3","_createElementVNode","_defineComponent","__name","setup","__props","store","useStore","appConfig","computed","getters","ROOT_STORE","appStatistics","isAuthUserAmin","AUTH_USER_STORE","userLoading","onBeforeMount","dispatch","_ctx","_cache","_component_router_view","_resolveComponent","_openBlock","_createElementBlock","_unref","_createCommentVNode","_createBlock","NotFound","__exports__"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[845],{4264:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});r(7658);var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(5801),c=r(9917);const l={key:0,id:"account-confirmation",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"AccountConfirmationView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),S=(0,n.Fl)((()=>t.query.token));function m(){S.value?_.dispatch(i.YN.ACTIONS.CONFIRM_ACCOUNT,{token:S.value}):r.push("/")}return(0,n.wF)((()=>m())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(e,t)=>{const r=(0,n.up)("router-link");return(0,a.SU)(d)?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n.Wm)(r,{class:"links",to:"/account-confirmation/resend"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("buttons.ACCOUNT-CONFIRMATION-RESEND"))+"? ",1)])),_:1})])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-785df978"]]);var m=S},8160:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});r(7658);var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(5801),c=r(9917);const l={key:0,id:"email-update",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"EmailUpdateView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.AUTH_USER_PROFILE])),S=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.IS_AUTHENTICATED])),m=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),p=(0,n.Fl)((()=>t.query.token));function R(){p.value?_.dispatch(i.YN.ACTIONS.CONFIRM_EMAIL,{token:p.value,refreshUser:S.value}):r.push("/")}return(0,n.wF)((()=>R())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(0,n.YP)((()=>m.value),(e=>{d.value.username&&e&&r.push("/")})),(e,t)=>{const r=(0,n.up)("router-link"),u=(0,n.up)("i18n-t");return(0,a.SU)(m)&&!(0,a.SU)(d).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n._)("span",null,[(0,n.Wm)(u,{keypath:"user.PROFILE.ERRORED_EMAIL_UPDATE"},{default:(0,n.w5)((()=>[(0,n.Wm)(r,{to:"/login"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("user.LOG_IN")),1)])),_:1})])),_:1})])])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-8c2ec9ce"]]);var m=S},6266:function(e,t,r){r.r(t),r.d(t,{default:function(){return d}});var n=r(6252),a=r(2262),s=r(5801),u=r(9917);const o=e=>((0,n.dD)("data-v-05463732"),e=e(),(0,n.Cn)(),e),i={key:0,id:"profile",class:"container view"},c=o((()=>(0,n._)("div",{id:"bottom"},null,-1)));var l=(0,n.aZ)({__name:"ProfileView",setup(e){const t=(0,u.o)(),r=(0,n.Fl)((()=>t.getters[s.YN.GETTERS.AUTH_USER_PROFILE]));return(e,t)=>{const s=(0,n.up)("router-view");return(0,a.SU)(r).username?((0,n.wg)(),(0,n.iD)("div",i,[(0,n.Wm)(s,{user:(0,a.SU)(r)},null,8,["user"]),c])):(0,n.kq)("",!0)}}}),E=r(3744);const _=(0,E.Z)(l,[["__scopeId","data-v-05463732"]]);var d=_},9453:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(2201),u=r(2179),o=r(7408),i=r(5801),c=r(9917);const l={key:0,id:"user",class:"view"},E={class:"box"};var _=(0,n.aZ)({__name:"UserView",props:{fromAdmin:{type:Boolean}},setup(e){const t=e,{fromAdmin:r}=(0,a.BK)(t),_=(0,s.yj)(),d=(0,c.o)(),S=(0,n.Fl)((()=>d.getters[i.RT.GETTERS.USER]));return(0,n.wF)((()=>{_.params.username&&"string"===typeof _.params.username&&d.dispatch(i.RT.ACTIONS.GET_USER,_.params.username)})),(0,n.Jd)((()=>{d.dispatch(i.RT.ACTIONS.EMPTY_USER)})),(e,t)=>(0,a.SU)(S).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(u.Z,{user:(0,a.SU)(S)},null,8,["user"]),(0,n._)("div",E,[(0,n.Wm)(o.Z,{user:(0,a.SU)(S),"from-admin":(0,a.SU)(r)},null,8,["user","from-admin"])])])):(0,n.kq)("",!0)}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-af7007f4"]]);var m=S}}]);
//# sourceMappingURL=profile.dd30724d.js.map
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[845],{4264:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});r(7658);var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(5801),c=r(9917);const l={key:0,id:"account-confirmation",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"AccountConfirmationView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),S=(0,n.Fl)((()=>t.query.token));function m(){S.value?_.dispatch(i.YN.ACTIONS.CONFIRM_ACCOUNT,{token:S.value}):r.push("/")}return(0,n.wF)((()=>m())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(e,t)=>{const r=(0,n.up)("router-link");return(0,a.SU)(d)?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n.Wm)(r,{class:"links",to:"/account-confirmation/resend"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("buttons.ACCOUNT-CONFIRMATION-RESEND"))+"? ",1)])),_:1})])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-785df978"]]);var m=S},8160:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});r(7658);var n=r(6252),a=r(2262),s=r(3577),u=r(2201),o=r(7167),i=r(5801),c=r(9917);const l={key:0,id:"email-update",class:"center-card with-margin"},E={class:"error-message"};var _=(0,n.aZ)({__name:"EmailUpdateView",setup(e){const t=(0,u.yj)(),r=(0,u.tv)(),_=(0,c.o)(),d=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.AUTH_USER_PROFILE])),S=(0,n.Fl)((()=>_.getters[i.YN.GETTERS.IS_AUTHENTICATED])),m=(0,n.Fl)((()=>_.getters[i.SY.GETTERS.ERROR_MESSAGES])),p=(0,n.Fl)((()=>t.query.token));function R(){p.value?_.dispatch(i.YN.ACTIONS.CONFIRM_EMAIL,{token:p.value,refreshUser:S.value}):r.push("/")}return(0,n.wF)((()=>R())),(0,n.Ah)((()=>_.commit(i.SY.MUTATIONS.EMPTY_ERROR_MESSAGES))),(0,n.YP)((()=>m.value),(e=>{d.value.username&&e&&r.push("/")})),(e,t)=>{const r=(0,n.up)("router-link"),u=(0,n.up)("i18n-t");return(0,a.SU)(m)&&!(0,a.SU)(d).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(o.Z),(0,n._)("p",E,[(0,n._)("span",null,(0,s.zw)(e.$t("error.SOMETHING_WRONG"))+".",1),(0,n._)("span",null,[(0,n.Wm)(u,{keypath:"user.PROFILE.ERRORED_EMAIL_UPDATE"},{default:(0,n.w5)((()=>[(0,n.Wm)(r,{to:"/login"},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.$t("user.LOG_IN")),1)])),_:1})])),_:1})])])])):(0,n.kq)("",!0)}}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-8c2ec9ce"]]);var m=S},6266:function(e,t,r){r.r(t),r.d(t,{default:function(){return d}});var n=r(6252),a=r(2262),s=r(5801),u=r(9917);const o=e=>((0,n.dD)("data-v-05463732"),e=e(),(0,n.Cn)(),e),i={key:0,id:"profile",class:"container view"},c=o((()=>(0,n._)("div",{id:"bottom"},null,-1)));var l=(0,n.aZ)({__name:"ProfileView",setup(e){const t=(0,u.o)(),r=(0,n.Fl)((()=>t.getters[s.YN.GETTERS.AUTH_USER_PROFILE]));return(e,t)=>{const s=(0,n.up)("router-view");return(0,a.SU)(r).username?((0,n.wg)(),(0,n.iD)("div",i,[(0,n.Wm)(s,{user:(0,a.SU)(r)},null,8,["user"]),c])):(0,n.kq)("",!0)}}}),E=r(3744);const _=(0,E.Z)(l,[["__scopeId","data-v-05463732"]]);var d=_},9453:function(e,t,r){r.r(t),r.d(t,{default:function(){return m}});var n=r(6252),a=r(2262),s=r(2201),u=r(2179),o=r(1585),i=r(5801),c=r(9917);const l={key:0,id:"user",class:"view"},E={class:"box"};var _=(0,n.aZ)({__name:"UserView",props:{fromAdmin:{type:Boolean}},setup(e){const t=e,{fromAdmin:r}=(0,a.BK)(t),_=(0,s.yj)(),d=(0,c.o)(),S=(0,n.Fl)((()=>d.getters[i.RT.GETTERS.USER]));return(0,n.wF)((()=>{_.params.username&&"string"===typeof _.params.username&&d.dispatch(i.RT.ACTIONS.GET_USER,_.params.username)})),(0,n.Jd)((()=>{d.dispatch(i.RT.ACTIONS.EMPTY_USER)})),(e,t)=>(0,a.SU)(S).username?((0,n.wg)(),(0,n.iD)("div",l,[(0,n.Wm)(u.Z,{user:(0,a.SU)(S)},null,8,["user"]),(0,n._)("div",E,[(0,n.Wm)(o.Z,{user:(0,a.SU)(S),"from-admin":(0,a.SU)(r)},null,8,["user","from-admin"])])])):(0,n.kq)("",!0)}}),d=r(3744);const S=(0,d.Z)(_,[["__scopeId","data-v-af7007f4"]]);var m=S}}]);
//# sourceMappingURL=profile.23749cd8.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkfittrackee_client"]=self["webpackChunkfittrackee_client"]||[]).push([[193],{7885:function(e,s,t){t.r(s),t.d(s,{default:function(){return A}});var a=t(6252),r=t(2262),l=t(3577),o=(t(7658),t(9150)),n=t(4998);const c={class:"chart-menu"},i={class:"chart-arrow"},u={class:"time-frames custom-checkboxes-group"},d={class:"time-frames-checkboxes custom-checkboxes"},p=["id","name","checked","onInput"],m={class:"chart-arrow"};var v=(0,a.aZ)({__name:"StatsMenu",emits:["arrowClick","timeFrameUpdate"],setup(e,{emit:s}){const t=(0,r.iH)("month"),o=["week","month","year"];function n(e){t.value=e,s("timeFrameUpdate",e)}return(e,r)=>((0,a.wg)(),(0,a.iD)("div",c,[(0,a._)("div",i,[(0,a._)("i",{class:"fa fa-chevron-left","aria-hidden":"true",onClick:r[0]||(r[0]=e=>s("arrowClick",!0))})]),(0,a._)("div",u,[(0,a._)("div",d,[((0,a.wg)(),(0,a.iD)(a.HY,null,(0,a.Ko)(o,(s=>(0,a._)("div",{class:"time-frame custom-checkbox",key:s},[(0,a._)("label",null,[(0,a._)("input",{type:"radio",id:s,name:s,checked:t.value===s,onInput:e=>n(s)},null,40,p),(0,a._)("span",null,(0,l.zw)(e.$t(`statistics.TIME_FRAMES.${s}`)),1)])]))),64))])]),(0,a._)("div",m,[(0,a._)("i",{class:"fa fa-chevron-right","aria-hidden":"true",onClick:r[1]||(r[1]=e=>s("arrowClick",!1))})])]))}}),k=t(3744);const _=(0,k.Z)(v,[["__scopeId","data-v-22d55de2"]]);var S=_,w=t(631);const f={class:"sports-menu"},h=["id","name","checked","onInput"],U={class:"sport-label"};var b=(0,a.aZ)({__name:"StatsSportsMenu",props:{userSports:null,selectedSportIds:{default:()=>[]}},emits:["selectedSportIdsUpdate"],setup(e,{emit:s}){const t=e,{t:n}=(0,o.QT)(),c=(0,a.f3)("sportColors"),{selectedSportIds:i}=(0,r.BK)(t),u=(0,a.Fl)((()=>(0,w.xH)(t.userSports,n)));function d(e){s("selectedSportIdsUpdate",e)}return(e,s)=>{const t=(0,a.up)("SportImage");return(0,a.wg)(),(0,a.iD)("div",f,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)((0,r.SU)(u),(e=>((0,a.wg)(),(0,a.iD)("label",{type:"checkbox",key:e.id,style:(0,l.j5)({color:e.color?e.color:(0,r.SU)(c)[e.label]})},[(0,a._)("input",{type:"checkbox",id:e.id,name:e.label,checked:(0,r.SU)(i).includes(e.id),onInput:s=>d(e.id)},null,40,h),(0,a.Wm)(t,{"sport-label":e.label,color:e.color},null,8,["sport-label","color"]),(0,a._)("span",U,(0,l.zw)(e.translatedLabel),1)],4)))),128))])}}});const I=b;var g=I,T=t(9318);const y={key:0,id:"user-statistics"};var C=(0,a.aZ)({__name:"index",props:{sports:null,user:null},setup(e){const s=e,{t:t}=(0,o.QT)(),{sports:l,user:c}=(0,r.BK)(s),i=(0,r.iH)("month"),u=(0,r.iH)(v(i.value)),d=(0,a.Fl)((()=>(0,w.xH)(s.sports,t))),p=(0,r.iH)(_(s.sports));function m(e){i.value=e,u.value=v(i.value)}function v(e){return(0,T.aZ)(new Date,e,s.user.weekm)}function k(e){u.value=(0,T.FN)(u.value,e,s.user.weekm)}function _(e){return e.map((e=>e.id))}function f(e){p.value.includes(e)?p.value=p.value.filter((s=>s!==e)):p.value.push(e)}return(0,a.YP)((()=>s.sports),(e=>{p.value=_(e)})),(e,s)=>(0,r.SU)(d)?((0,a.wg)(),(0,a.iD)("div",y,[(0,a.Wm)(S,{onTimeFrameUpdate:m,onArrowClick:k}),(0,a.Wm)(n.Z,{sports:(0,r.SU)(l),user:(0,r.SU)(c),chartParams:u.value,"displayed-sport-ids":p.value,fullStats:!0},null,8,["sports","user","chartParams","displayed-sport-ids"]),(0,a.Wm)(g,{"selected-sport-ids":p.value,"user-sports":(0,r.SU)(l),onSelectedSportIdsUpdate:f},null,8,["selected-sport-ids","user-sports"])])):(0,a.kq)("",!0)}});const F=(0,k.Z)(C,[["__scopeId","data-v-30799d13"]]);var Z=F,x=t(5630),D=t(5801),H=t(9917);const E={id:"statistics",class:"view"},R={key:0,class:"container"};var W=(0,a.aZ)({__name:"StatisticsView",setup(e){const s=(0,H.o)(),t=(0,a.Fl)((()=>s.getters[D.YN.GETTERS.AUTH_USER_PROFILE])),o=(0,a.Fl)((()=>s.getters[D.O8.GETTERS.SPORTS].filter((e=>t.value.sports_list.includes(e.id)))));return(e,s)=>{const n=(0,a.up)("Card");return(0,a.wg)(),(0,a.iD)("div",E,[(0,r.SU)(t).username?((0,a.wg)(),(0,a.iD)("div",R,[(0,a.Wm)(n,null,{title:(0,a.w5)((()=>[(0,a.Uk)((0,l.zw)(e.$t("statistics.STATISTICS")),1)])),content:(0,a.w5)((()=>[(0,a.Wm)(Z,{class:(0,l.C_)({"stats-disabled":0===(0,r.SU)(t).nb_workouts}),user:(0,r.SU)(t),sports:(0,r.SU)(o)},null,8,["class","user","sports"])])),_:1}),0===(0,r.SU)(t).nb_workouts?((0,a.wg)(),(0,a.j4)(x.Z,{key:0})):(0,a.kq)("",!0)])):(0,a.kq)("",!0)])}}});const P=(0,k.Z)(W,[["__scopeId","data-v-2e341d4e"]]);var A=P}}]);
//# sourceMappingURL=statistics.9cd652fd.js.map
//# sourceMappingURL=statistics.eaf4afd3.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,31 @@
"""Add date_format for date display to user preferences in DB
Revision ID: bf13b8f5589d
Revises: 84d840ce853b
Create Date: 2022-10-25 18:53:59.378423
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'bf13b8f5589d'
down_revision = '5b936821326d'
branch_labels = None
depends_on = None
def upgrade():
op.add_column(
'users', sa.Column('date_format', sa.String(length=50), nullable=True)
)
op.execute("UPDATE users SET date_format = 'MM/dd/yyyy'")
op.alter_column('users', 'date_format', nullable=False)
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'date_format')
# ### end Alembic commands ###

View File

@ -235,6 +235,27 @@ class TestUserRegistration(ApiTestCaseMixin):
assert data['status'] == 'success'
assert 'auth_token' not in data
def test_it_creates_user_with_default_date_format(
self, app: Flask
) -> None:
client = app.test_client()
username = self.random_string()
client.post(
'/api/auth/register',
data=json.dumps(
dict(
username=username,
email=self.random_email(),
password=self.random_string(),
)
),
content_type='application/json',
)
new_user = User.query.filter_by(username=username).first()
assert new_user.date_format == 'MM/dd/yyyy'
@pytest.mark.parametrize(
'input_language,expected_language',
[('en', 'en'), ('fr', 'fr'), ('invalid', 'en'), (None, 'en')],
@ -1394,6 +1415,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
language=input_language,
imperial_units=True,
display_ascent=False,
date_format='yyyy-MM-dd',
)
),
headers=dict(Authorization=f'Bearer {auth_token}'),
@ -1407,6 +1429,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
assert data['data']['imperial_units'] is True
assert data['data']['language'] == expected_language
assert data['data']['timezone'] == 'America/New_York'
assert data['data']['date_format'] == 'yyyy-MM-dd'
assert data['data']['weekm'] is True
@pytest.mark.parametrize(

View File

@ -173,6 +173,7 @@ def register_user() -> Union[Tuple[Dict, int], HttpResponse]:
if not user:
new_user = User(username=username, email=email, password=password)
new_user.timezone = 'Europe/Paris'
new_user.date_format = 'MM/dd/yyyy'
new_user.confirmation_token = secrets.token_urlsafe(30)
new_user.language = language
db.session.add(new_user)
@ -780,6 +781,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
"bio": null,
"birth_date": null,
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"date_format": "MM/dd/yyyy",
"display_ascent": true,
"email": "sam@example.com",
"first_name": null,
@ -854,6 +856,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
}
:<json boolean display_ascent: display highest ascent records and total
:<json string date_format: the format used to display dates in the app
:<json boolean imperial_units: display distance in imperial units
:<json string language: language preferences
:<json string timezone: user time zone
@ -874,6 +877,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
# get post data
post_data = request.get_json()
user_mandatory_data = {
'date_format',
'display_ascent',
'imperial_units',
'language',
@ -883,6 +887,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
if not post_data or not post_data.keys() >= user_mandatory_data:
return InvalidPayloadErrorResponse()
date_format = post_data.get('date_format')
display_ascent = post_data.get('display_ascent')
imperial_units = post_data.get('imperial_units')
language = get_language(post_data.get('language'))
@ -890,6 +895,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
weekm = post_data.get('weekm')
try:
auth_user.date_format = date_format
auth_user.display_ascent = display_ascent
auth_user.imperial_units = imperial_units
auth_user.language = language

View File

@ -33,6 +33,7 @@ class User(BaseModel):
bio = db.Column(db.String(200), nullable=True)
picture = db.Column(db.String(255), nullable=True)
timezone = db.Column(db.String(50), nullable=True)
date_format = db.Column(db.String(50), nullable=True)
# does the week start Monday?
weekm = db.Column(db.Boolean, default=False, nullable=False)
workouts = db.relationship(
@ -190,6 +191,7 @@ class User(BaseModel):
serialized_user = {
**serialized_user,
**{
'date_format': self.date_format,
'display_ascent': self.display_ascent,
'imperial_units': self.imperial_units,
'language': self.language,

View File

@ -62,9 +62,10 @@
{{ $t('user.PROFILE.REGISTRATION_DATE') }}
</span>
{{
format(
getDateWithTZ(user.created_at, authUser.timezone),
'dd/MM/yyyy HH:mm'
formatDate(
user.created_at,
authUser.timezone,
authUser.date_format
)
}}
</td>
@ -130,7 +131,6 @@
</template>
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
Ref,
@ -152,7 +152,7 @@
import { IAuthUserProfile, IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { getQuery, sortList } from '@/utils/api'
import { getDateWithTZ } from '@/utils/dates'
import { formatDate } from '@/utils/dates'
const store = useStore()
const route = useRoute()

View File

@ -86,7 +86,7 @@
align-items: center;
justify-content: space-between;
span {
padding: 2px 5px;
padding: 2px;
}
.record-type {
flex-grow: 1;
@ -94,7 +94,12 @@
.record-value {
font-weight: bold;
white-space: nowrap;
padding-right: $default-padding * 2;
padding-right: $default-padding;
}
.record-date {
white-space: nowrap;
min-width: 30%;
text-align: right;
}
}
}

View File

@ -43,7 +43,8 @@
translateSports(props.sports, t),
props.user.timezone,
props.user.imperial_units,
props.user.display_ascent
props.user.display_ascent,
props.user.date_format
)
)
</script>

View File

@ -130,6 +130,8 @@
import { TAppConfig } from '@/types/application'
import { IAuthUserProfile, IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { formatDate, getDateFormat } from '@/utils/dates'
import { localeFromLanguage } from '@/utils/locales'
interface Props {
user: IUserProfile
@ -142,17 +144,28 @@
const store = useStore()
const { user, fromAdmin } = toRefs(props)
const language: ComputedRef<string> = computed(
() => store.getters[ROOT_STORE.GETTERS.LANGUAGE]
)
const authUser: ComputedRef<IAuthUserProfile> = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.AUTH_USER_PROFILE]
)
const registrationDate = computed(() =>
props.user.created_at
? format(new Date(props.user.created_at), 'dd/MM/yyyy HH:mm')
? formatDate(
props.user.created_at,
authUser.value.timezone,
authUser.value.date_format
)
: ''
)
const birthDate = computed(() =>
props.user.birth_date
? format(new Date(props.user.birth_date), 'dd/MM/yyyy')
? format(
new Date(props.user.birth_date),
`${getDateFormat(authUser.value.date_format, language.value)}`,
{ locale: localeFromLanguage[language.value] }
)
: ''
)
const isSuccess = computed(

View File

@ -2,9 +2,11 @@
<div id="user-preferences" class="description-list">
<dl>
<dt>{{ $t('user.PROFILE.LANGUAGE') }}:</dt>
<dd>{{ language }}</dd>
<dd>{{ userLanguage }}</dd>
<dt>{{ $t('user.PROFILE.TIMEZONE') }}:</dt>
<dd>{{ timezone }}</dd>
<dt>{{ $t('user.PROFILE.DATE_FORMAT') }}:</dt>
<dd>{{ getDateFormat(date_format, appLanguage) }}</dd>
<dt>{{ $t('user.PROFILE.FIRST_DAY_OF_WEEK') }}:</dt>
<dd>{{ $t(`user.PROFILE.${fistDayOfWeek}`) }}</dd>
<dt>{{ $t('user.PROFILE.UNITS.LABEL') }}:</dt>
@ -28,9 +30,12 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { computed, ComputedRef } from 'vue'
import { ROOT_STORE } from '@/store/constants'
import { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { getDateFormat } from '@/utils/dates'
import { languageLabels } from '@/utils/locales'
interface Props {
@ -38,7 +43,12 @@
}
const props = defineProps<Props>()
const language = computed(() =>
const store = useStore()
const appLanguage: ComputedRef<string> = computed(
() => store.getters[ROOT_STORE.GETTERS.LANGUAGE]
)
const userLanguage = computed(() =>
props.user.language
? languageLabels[props.user.language]
: languageLabels['en']
@ -47,6 +57,9 @@
const timezone = computed(() =>
props.user.timezone ? props.user.timezone : 'Europe/Paris'
)
const date_format = computed(() =>
props.user.date_format ? props.user.date_format : 'MM/dd/yyyy'
)
const display_ascent = computed(() =>
props.user.display_ascent ? 'DISPLAYED' : 'HIDDEN'
)

View File

@ -65,11 +65,12 @@
import { ComputedRef, computed, reactive, onMounted, onUnmounted } from 'vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IUserProfile, IUserPayload } from '@/types/user'
import { IUserProfile, IUserPayload, IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { formatDate } from '@/utils/dates'
interface Props {
user: IUserProfile
user: IAuthUserProfile
}
const props = defineProps<Props>()
@ -84,7 +85,11 @@
})
const registrationDate = computed(() =>
props.user.created_at
? format(new Date(props.user.created_at), 'dd/MM/yyyy HH:mm')
? formatDate(
props.user.created_at,
props.user.timezone,
props.user.date_format
)
: ''
)
const loading = computed(

View File

@ -23,6 +23,22 @@
@updateTimezone="updateTZ"
/>
</label>
<label class="form-items">
{{ $t('user.PROFILE.DATE_FORMAT') }}
<select
id="date_format"
v-model="userForm.date_format"
:disabled="loading"
>
<option
v-for="dateFormat in dateFormatOptions"
:value="dateFormat.value"
:key="dateFormat.value"
>
{{ dateFormat.label }}
</option>
</select>
</label>
<div class="form-items form-checkboxes">
<span class="checkboxes-label">
{{ $t('user.PROFILE.FIRST_DAY_OF_WEEK') }}
@ -106,6 +122,7 @@
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IUserPreferencesPayload, IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { availableDateFormatOptions } from '@/utils/dates'
import { availableLanguages } from '@/utils/locales'
interface Props {
@ -120,6 +137,7 @@
imperial_units: false,
language: '',
timezone: 'Europe/Paris',
date_format: 'dd/MM/yyyy',
weekm: false,
})
const weekStart = [
@ -158,6 +176,13 @@
const errorMessages: ComputedRef<string | string[] | null> = computed(
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
)
const dateFormatOptions = computed(() =>
availableDateFormatOptions(
new Date().toUTCString(),
props.user.timezone,
userForm.language
)
)
onMounted(() => {
if (props.user) {
@ -170,6 +195,7 @@
userForm.imperial_units = user.imperial_units ? user.imperial_units : false
userForm.language = user.language ? user.language : 'en'
userForm.timezone = user.timezone ? user.timezone : 'Europe/Paris'
userForm.date_format = user.date_format ? user.date_format : 'dd/MM/yyyy'
userForm.weekm = user.weekm ? user.weekm : false
}
function updateProfile() {

View File

@ -50,9 +50,10 @@
<dt>{{ capitalize($t('oauth2.APP.ISSUE_AT')) }}:</dt>
<dd>
{{
format(
getDateWithTZ(client.issued_at, authUser.timezone),
'dd/MM/yyyy HH:mm'
formatDate(
client.issued_at,
authUser.timezone,
authUser.date_format
)
}}
</dd>
@ -105,7 +106,6 @@
</template>
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
Ref,
@ -124,7 +124,7 @@
import { IOAuth2Client } from '@/types/oauth'
import { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { getDateWithTZ } from '@/utils/dates'
import { formatDate } from '@/utils/dates'
interface Props {
authUser: IAuthUserProfile

View File

@ -9,9 +9,10 @@
<span class="app-issued-at">
{{ $t('oauth2.APP.ISSUE_AT') }}
{{
format(
getDateWithTZ(client.issued_at, authUser.timezone),
'dd/MM/yyyy HH:mm'
formatDate(
client.issued_at,
authUser.timezone,
authUser.date_format
)
}}
</span>
@ -34,7 +35,6 @@
</template>
<script setup lang="ts">
import { format } from 'date-fns'
import { ComputedRef, computed, onBeforeMount, toRefs, watch } from 'vue'
import { LocationQuery, useRoute } from 'vue-router'
@ -45,7 +45,7 @@
import { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { defaultPage, getNumberQueryValue } from '@/utils/api'
import { getDateWithTZ } from '@/utils/dates'
import { formatDate } from '@/utils/dates'
interface Props {
authUser: IAuthUserProfile

View File

@ -29,10 +29,7 @@
class="workout-date"
v-if="workout.workout_date && user"
:title="
format(
getDateWithTZ(workout.workout_date, user.timezone),
'dd/MM/yyyy HH:mm'
)
formatDate(workout.workout_date, user.timezone, user.date_format)
"
>
{{
@ -141,7 +138,7 @@
</template>
<script setup lang="ts">
import { Locale, format, formatDistance } from 'date-fns'
import { Locale, formatDistance } from 'date-fns'
import { ComputedRef, computed, toRefs, withDefaults } from 'vue'
import StaticMap from '@/components/Common/StaticMap.vue'
@ -151,7 +148,7 @@
import { IUserProfile } from '@/types/user'
import { IWorkout } from '@/types/workouts'
import { useStore } from '@/use/useStore'
import { getDateWithTZ } from '@/utils/dates'
import { formatDate } from '@/utils/dates'
interface Props {
user: IUserProfile

View File

@ -131,7 +131,8 @@
getDateWithTZ(
props.workoutData.workout.workout_date,
props.authUser.timezone
)
),
props.authUser.date_format
)
return {
ascent: segment ? segment.ascent : workout.ascent,

View File

@ -84,9 +84,10 @@
{{ $t('workouts.DATE') }}
</span>
{{
format(
getDateWithTZ(workout.workout_date, user.timezone),
'dd/MM/yyyy HH:mm'
formatDate(
workout.workout_date,
user.timezone,
user.date_format
)
}}
</td>
@ -162,7 +163,6 @@
</template>
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
Ref,
@ -186,7 +186,7 @@
import { IWorkout, TWorkoutsPayload } from '@/types/workouts'
import { useStore } from '@/use/useStore'
import { getQuery, sortList, workoutsPayloadKeys } from '@/utils/api'
import { getDateWithTZ } from '@/utils/dates'
import { formatDate } from '@/utils/dates'
import { getSportColor, getSportLabel } from '@/utils/sports'
import { convertDistance } from '@/utils/units'
import { defaultOrder } from '@/utils/workouts'

View File

@ -52,6 +52,7 @@
"BACK_TO_PROFILE": "Zurück zum Profil",
"BIO": "Biographie",
"BIRTH_DATE": "Geburtsdatum",
"DATE_FORMAT": "Datumsanzeigeformat",
"EDIT": "Profil bearbeiten",
"EDIT_PREFERENCES": "Einstellungen ändern",
"EDIT_SPORTS_PREFERENCES": "Einstellungen für Sportarten ändern",

View File

@ -52,6 +52,7 @@
"BACK_TO_PROFILE": "Back to profile",
"BIO": "Bio",
"BIRTH_DATE": "Birth date",
"DATE_FORMAT": "Date display format",
"EDIT": "Edit profile",
"EDIT_PREFERENCES": "Edit preferences",
"EDIT_SPORTS_PREFERENCES": "Edit sports preferences",

View File

@ -52,6 +52,7 @@
"BACK_TO_PROFILE": "Revenir au profil",
"BIO": "Bio",
"BIRTH_DATE": "Date de naissance",
"DATE_FORMAT": "Format d'affichage de la date",
"EDIT": "Modifier le profil",
"EDIT_PREFERENCES": "Modifier les préférences",
"EDIT_SPORTS_PREFERENCES": "Modifier les préférences des sports",

View File

@ -29,6 +29,7 @@ export interface IAuthUserProfile extends IUserProfile {
imperial_units: boolean
language: string | null
timezone: string
date_format: string
weekm: boolean
}
@ -64,6 +65,7 @@ export interface IUserPreferencesPayload {
imperial_units: boolean
language: string
timezone: string
date_format: string
weekm: boolean
}

View File

@ -11,6 +11,11 @@ import {
} from 'date-fns'
import { utcToZonedTime } from 'date-fns-tz'
import createI18n from '@/i18n'
import { localeFromLanguage } from '@/utils/locales'
const { locale } = createI18n.global
export const getStartDate = (
duration: string,
day: Date,
@ -70,11 +75,70 @@ export const formatWorkoutDate = (
if (!dateFormat) {
dateFormat = 'yyyy/MM/dd'
}
dateFormat = getDateFormat(dateFormat, locale.value)
if (!timeFormat) {
timeFormat = 'HH:mm'
}
return {
workout_date: format(dateTime, dateFormat),
workout_date: format(dateTime, dateFormat, {
locale: localeFromLanguage[locale.value],
}),
workout_time: format(dateTime, timeFormat),
}
}
const availableDateFormats = [
'MM/dd/yyyy',
'dd/MM/yyyy',
'yyyy-MM-dd',
'date_string',
]
const dateStringFormats: Record<string, string> = {
de: 'do MMM yyyy',
en: 'MMM. do, yyyy',
fr: 'd MMM yyyy',
}
export const getDateFormat = (dateFormat: string, language: string): string => {
return dateFormat === 'date_string' ? dateStringFormats[language] : dateFormat
}
export const formatDate = (
dateString: string,
timezone: string,
dateFormat: string,
withTime = true,
language: string | null = null
): string => {
if (!language) {
language = locale.value
}
return format(
getDateWithTZ(dateString, timezone),
`${getDateFormat(dateFormat, language)}${withTime ? ' HH:mm' : ''}`,
{ locale: localeFromLanguage[language] }
)
}
export const availableDateFormatOptions = (
inputDate: string,
timezone: string,
language: string | null = null
) => {
const l: string = language ? language : locale.value
const options: Record<string, string>[] = []
availableDateFormats.map((df) => {
const dateFormat = getDateFormat(df, l)
options.push({
label: `${dateFormat} - ${formatDate(
inputDate,
timezone,
dateFormat,
false,
l
)}`,
value: df,
})
})
return options
}

View File

@ -1,13 +1,17 @@
import createI18n from '@/i18n'
import { ITranslatedSport } from '@/types/sports'
import { TUnit } from '@/types/units'
import { ICardRecord, IRecord, IRecordsBySports } from '@/types/workouts'
import { formatWorkoutDate, getDateWithTZ } from '@/utils/dates'
import { formatDate, getDateFormat } from '@/utils/dates'
import { convertDistance, units } from '@/utils/units'
const { locale } = createI18n.global
export const formatRecord = (
record: IRecord,
tz: string,
useImperialUnits: boolean
useImperialUnits: boolean,
date_format: string
): Record<string, string | number> => {
const distanceUnitFrom: TUnit = 'km'
const distanceUnitTo: TUnit = useImperialUnits
@ -53,8 +57,7 @@ export const formatRecord = (
)
}
return {
workout_date: formatWorkoutDate(getDateWithTZ(record.workout_date, tz))
.workout_date,
workout_date: formatDate(record.workout_date, tz, date_format, false),
workout_id: record.workout_id,
id: record.id,
record_type: record.record_type,
@ -73,9 +76,11 @@ export const getRecordsBySports = (
translatedSports: ITranslatedSport[],
tz: string,
useImperialUnits: boolean,
display_ascent: boolean
): IRecordsBySports =>
records
display_ascent: boolean,
date_format: string
): IRecordsBySports => {
date_format = getDateFormat(date_format, locale.value)
return records
.filter((r) => (display_ascent ? true : r.record_type !== 'HA'))
.reduce((sportList: IRecordsBySports, record) => {
const sport = translatedSports.find((s) => s.id === record.sport_id)
@ -88,8 +93,9 @@ export const getRecordsBySports = (
}
}
sportList[sport.translatedLabel].records.push(
formatRecord(record, tz, useImperialUnits)
formatRecord(record, tz, useImperialUnits, date_format)
)
}
return sportList
}, {})
}

View File

@ -5,6 +5,9 @@ import {
incrementDate,
getStartDate,
formatWorkoutDate,
formatDate,
availableDateFormatOptions,
getDateFormat,
} from '@/utils/dates'
describe('startDate (week starting Sunday)', () => {
@ -240,3 +243,158 @@ describe('formatWorkoutDate', () => {
})
})
})
describe('formatDate', () => {
const dateString = 'Tue, 01 Nov 2022 00:00:00 GMT'
const testsParams = [
{
description:
'format date for "Europe/Paris" timezone and "dd/MM/yyyy" format (with time)',
inputParams: {
timezone: 'Europe/Paris',
dateFormat: 'dd/MM/yyyy',
withTime: true,
},
expectedDate: '01/11/2022 01:00',
},
{
description:
'format date for "America/New_York" timezone and "MM/dd/yyyy" format (w/o time)',
inputParams: {
timezone: 'America/New_York',
dateFormat: 'MM/dd/yyyy',
withTime: false,
},
expectedDate: '10/31/2022',
},
]
testsParams.map((testParams) => {
it(testParams.description, () => {
assert.deepEqual(
formatDate(
dateString,
testParams.inputParams.timezone,
testParams.inputParams.dateFormat,
testParams.inputParams.withTime
),
testParams.expectedDate
)
})
})
})
describe('formatDate (w/ default value)', () => {
it('format date for "Europe/Paris" timezone and "dd/MM/yyyy" format', () => {
assert.deepEqual(
formatDate('Tue, 01 Nov 2022 00:00:00 GMT', 'Europe/Paris', 'yyyy-MM-dd'),
'2022-11-01 01:00'
)
})
})
describe('getDateFormat', () => {
const testsParams = [
{
inputParams: {
dateFormat: 'dd/MM/yyyy',
language: 'en',
},
expectedFormat: 'dd/MM/yyyy',
},
{
inputParams: {
dateFormat: 'MM/dd/yyyy',
language: 'en',
},
expectedFormat: 'MM/dd/yyyy',
},
{
inputParams: {
dateFormat: 'yyyy-MM-dd',
language: 'en',
},
expectedFormat: 'yyyy-MM-dd',
},
{
inputParams: {
dateFormat: 'date_string',
language: 'en',
},
expectedFormat: 'MMM. do, yyyy',
},
{
inputParams: {
dateFormat: 'date_string',
language: 'fr',
},
expectedFormat: 'd MMM yyyy',
},
{
inputParams: {
dateFormat: 'date_string',
language: 'de',
},
expectedFormat: 'do MMM yyyy',
},
]
testsParams.map((testParams) => {
it(`get date format for "${testParams.inputParams.language}" and "${testParams.inputParams.dateFormat}" `, () => {
assert.deepEqual(
getDateFormat(
testParams.inputParams.dateFormat,
testParams.inputParams.language
),
testParams.expectedFormat
)
})
})
})
describe('availableDateFormatOptions', () => {
const inputDate = `Sun, 9 Oct 2022 18:18:41 GMT`
const inputTimezone = `Europe/Paris`
const testsParams = [
{
inputLanguage: 'en',
expectedOptions: [
{ label: 'MM/dd/yyyy - 10/09/2022', value: 'MM/dd/yyyy' },
{ label: 'dd/MM/yyyy - 09/10/2022', value: 'dd/MM/yyyy' },
{ label: 'yyyy-MM-dd - 2022-10-09', value: 'yyyy-MM-dd' },
{ label: 'MMM. do, yyyy - Oct. 9th, 2022', value: 'date_string' },
],
},
{
inputLanguage: 'fr',
expectedOptions: [
{ label: 'MM/dd/yyyy - 10/09/2022', value: 'MM/dd/yyyy' },
{ label: 'dd/MM/yyyy - 09/10/2022', value: 'dd/MM/yyyy' },
{ label: 'yyyy-MM-dd - 2022-10-09', value: 'yyyy-MM-dd' },
{ label: 'd MMM yyyy - 9 oct. 2022', value: 'date_string' },
],
},
{
inputLanguage: 'de',
expectedOptions: [
{ label: 'MM/dd/yyyy - 10/09/2022', value: 'MM/dd/yyyy' },
{ label: 'dd/MM/yyyy - 09/10/2022', value: 'dd/MM/yyyy' },
{ label: 'yyyy-MM-dd - 2022-10-09', value: 'yyyy-MM-dd' },
{ label: 'do MMM yyyy - 9. Okt. 2022', value: 'date_string' },
],
},
]
testsParams.map((testParams) => {
it(`returns available options for ${testParams.inputLanguage} locale`, () => {
assert.deepEqual(
availableDateFormatOptions(
inputDate,
inputTimezone,
testParams.inputLanguage
),
testParams.expectedOptions
)
})
})
})

View File

@ -19,6 +19,7 @@ describe('formatRecord', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 9,
@ -41,6 +42,7 @@ describe('formatRecord', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/MM/dd'
},
expected: {
id: 10,
@ -63,6 +65,7 @@ describe('formatRecord', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/MM/dd'
},
expected: {
id: 11,
@ -85,12 +88,13 @@ describe('formatRecord', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'dd/MM/yyyy'
},
expected: {
id: 12,
record_type: 'MS',
value: '18 km/h',
workout_date: '2019/07/08',
workout_date: '08/07/2019',
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
},
@ -107,12 +111,13 @@ describe('formatRecord', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'MMM. do, yyyy'
},
expected: {
id: 13,
record_type: 'HA',
value: '100 m',
workout_date: '2019/07/07',
workout_date: 'Jul. 7th, 2019',
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
},
@ -123,7 +128,8 @@ describe('formatRecord', () => {
formatRecord(
testParams.inputParams.record,
testParams.inputParams.timezone,
false
false,
testParams.inputParams.date_format
),
testParams.expected
)
@ -146,6 +152,7 @@ describe('formatRecord after conversion', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 9,
@ -168,12 +175,13 @@ describe('formatRecord after conversion', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 10,
record_type: 'FD',
value: '11.185 mi',
workout_date: '2019/07/08',
workout_date: '2019/08/07',
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
},
@ -190,6 +198,7 @@ describe('formatRecord after conversion', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 11,
@ -212,12 +221,13 @@ describe('formatRecord after conversion', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 12,
record_type: 'MS',
value: '11.18 mi/h',
workout_date: '2019/07/08',
workout_date: '2019/08/07',
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
},
@ -234,6 +244,7 @@ describe('formatRecord after conversion', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
timezone: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
id: 13,
@ -250,7 +261,8 @@ describe('formatRecord after conversion', () => {
formatRecord(
testParams.inputParams.record,
testParams.inputParams.timezone,
true
true,
testParams.inputParams.date_format
),
testParams.expected
)
@ -272,7 +284,8 @@ describe('formatRecord (invalid record type)', () => {
workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
},
'Europe/Paris',
false
false,
'yyyy/dd/MM'
)
).to.throw(
'Invalid record type, expected: "AS", "FD", "HA", "LD", "MD", got: "M"'
@ -287,6 +300,7 @@ describe('getRecordsBySports', () => {
input: {
records: [],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {},
},
@ -305,6 +319,7 @@ describe('getRecordsBySports', () => {
},
],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
'Cycling (Sport)': {
@ -355,6 +370,7 @@ describe('getRecordsBySports', () => {
},
],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
'Cycling (Sport)': {
@ -385,7 +401,7 @@ describe('getRecordsBySports', () => {
id: 10,
record_type: 'FD',
value: '18 km',
workout_date: '2019/07/08',
workout_date: '2019/08/07',
workout_id: 'n6JcLPQt3QtZWFfiSnYm4C',
},
],
@ -401,7 +417,8 @@ describe('getRecordsBySports', () => {
translatedSports,
testParams.input.tz,
false,
true
true,
testParams.input.date_format
),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
@ -418,6 +435,7 @@ describe('getRecordsBySports after conversion', () => {
input: {
records: [],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {},
},
@ -436,6 +454,7 @@ describe('getRecordsBySports after conversion', () => {
},
],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
'Cycling (Sport)': {
@ -486,6 +505,7 @@ describe('getRecordsBySports after conversion', () => {
},
],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
'Cycling (Sport)': {
@ -516,7 +536,7 @@ describe('getRecordsBySports after conversion', () => {
id: 10,
record_type: 'FD',
value: '11.185 mi',
workout_date: '2019/07/08',
workout_date: '2019/08/07',
workout_id: 'n6JcLPQt3QtZWFfiSnYm4C',
},
],
@ -532,7 +552,8 @@ describe('getRecordsBySports after conversion', () => {
translatedSports,
testParams.input.tz,
true,
true
true,
testParams.input.date_format
),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
@ -549,6 +570,7 @@ describe('getRecordsBySports with HA record', () => {
input: {
records: [],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {},
},
@ -576,6 +598,7 @@ describe('getRecordsBySports with HA record', () => {
},
],
tz: 'Europe/Paris',
date_format: 'yyyy/dd/MM'
},
expected: {
'Cycling (Sport)': {
@ -602,7 +625,8 @@ describe('getRecordsBySports with HA record', () => {
translatedSports,
testParams.input.tz,
false,
false
false,
testParams.input.date_format
),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore