@saooti/octopus-sdk 33.1.3 → 33.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +1 -0
  2. package/index.ts +5 -0
  3. package/package.json +1 -3
  4. package/src/App.vue +1 -1
  5. package/src/assets/_utilities.scss +532 -0
  6. package/src/assets/bootstrap.scss +231 -0
  7. package/src/assets/form.scss +3 -46
  8. package/src/assets/general.scss +10 -58
  9. package/src/assets/multiselect.scss +8 -3
  10. package/src/assets/octopus-library.scss +2 -4
  11. package/src/components/display/categories/CategoryChooser.vue +2 -2
  12. package/src/components/display/categories/CategoryFilter.vue +60 -46
  13. package/src/components/display/categories/CategoryList.vue +22 -19
  14. package/src/components/display/comments/AddCommentModal.vue +60 -67
  15. package/src/components/display/comments/CommentBasicView.vue +3 -4
  16. package/src/components/display/comments/CommentInput.vue +4 -4
  17. package/src/components/display/comments/CommentItem.vue +2 -2
  18. package/src/components/display/comments/CommentPlayer.vue +2 -2
  19. package/src/components/display/emission/EmissionChooser.vue +1 -1
  20. package/src/components/display/emission/EmissionItem.vue +2 -1
  21. package/src/components/display/emission/EmissionPlayerItem.vue +0 -11
  22. package/src/components/display/filter/AdvancedSearch.vue +2 -2
  23. package/src/components/display/filter/MonetizableFilter.vue +1 -1
  24. package/src/components/display/filter/RubriqueChoice.vue +1 -1
  25. package/src/components/display/organisation/OrganisationChooser.vue +1 -1
  26. package/src/components/display/participant/ParticipantItem.vue +2 -1
  27. package/src/components/display/playlist/PlaylistItem.vue +3 -2
  28. package/src/components/display/podcasts/ParticipantDescription.vue +2 -1
  29. package/src/components/display/podcasts/PodcastImage.vue +3 -3
  30. package/src/components/display/podcasts/PodcastInlineList.vue +1 -1
  31. package/src/components/display/podcasts/PodcastInlineListClassic.vue +1 -1
  32. package/src/components/display/podcasts/PodcastInlineListTemplate.vue +6 -2
  33. package/src/components/display/podcasts/PodcastItemInfo.vue +2 -2
  34. package/src/components/display/podcasts/PodcastPlayBar.vue +9 -35
  35. package/src/components/display/podcasts/TagList.vue +0 -2
  36. package/src/components/display/rubriques/RubriqueChooser.vue +2 -2
  37. package/src/components/display/rubriques/RubriqueList.vue +25 -20
  38. package/src/components/display/sharing/PlayerParameters.vue +76 -99
  39. package/src/components/display/sharing/ShareButtons.vue +3 -5
  40. package/src/components/display/sharing/ShareButtonsIntern.vue +1 -1
  41. package/src/components/display/sharing/ShareDistribution.vue +11 -10
  42. package/src/components/display/sharing/SharePlayer.vue +3 -0
  43. package/src/components/display/sharing/SubscribeButtons.vue +1 -1
  44. package/src/components/form/ClassicCheckbox.vue +73 -14
  45. package/src/components/form/ClassicLoading.vue +5 -1
  46. package/src/components/form/ClassicRadio.vue +12 -3
  47. package/src/components/form/ClassicSelect.vue +2 -9
  48. package/src/components/misc/Accordion.vue +76 -0
  49. package/src/components/misc/ErrorMessage.vue +2 -1
  50. package/src/components/misc/HomeDropdown.vue +66 -63
  51. package/src/components/misc/Nav.vue +99 -0
  52. package/src/components/misc/Popover.vue +139 -98
  53. package/src/components/misc/ProgressBar.vue +96 -0
  54. package/src/components/misc/Spinner.vue +37 -0
  55. package/src/components/misc/TopBar.vue +1 -1
  56. package/src/components/misc/modal/ClassicModal.vue +140 -0
  57. package/src/components/misc/modal/ClipboardModal.vue +25 -40
  58. package/src/components/misc/modal/MessageModal.vue +45 -60
  59. package/src/components/misc/modal/NewsletterModal.vue +85 -94
  60. package/src/components/misc/modal/QrCodeModal.vue +19 -36
  61. package/src/components/misc/modal/ShareModalPlayer.vue +72 -133
  62. package/src/components/misc/player/Player.vue +0 -6
  63. package/src/components/misc/player/PlayerCompact.vue +5 -4
  64. package/src/components/misc/player/PlayerLarge.vue +13 -9
  65. package/src/components/misc/player/PlayerProgressBar.vue +10 -48
  66. package/src/components/mixins/player/playerLogic.ts +3 -3
  67. package/src/components/pages/Podcast.vue +1 -1
  68. package/src/assets/bootstrap-diff.scss +0 -195
  69. package/src/assets/modal.scss +0 -49
@@ -9,86 +9,89 @@
9
9
  >
10
10
  {{ $t('My space') }}
11
11
  </button>
12
- <div
13
- class="dropdown btn-group"
12
+ <button
13
+ id="home-dropdown"
14
+ class="btn m-1 admin-button saooti-user"
15
+ :title="$t('User menu')"
16
+ />
17
+ <Popover
18
+ target="home-dropdown"
19
+ :only-click="true"
20
+ :is-fixed="true"
21
+ :left-pos="true"
14
22
  >
15
- <button
16
- class="btn dropdown-toggle m-1 admin-button dropdown-toggle-no-caret saooti-user"
17
- data-bs-toggle="dropdown"
18
- aria-expanded="false"
19
- :title="$t('User menu')"
20
- />
21
- <div class="dropdown-menu dropdown-menu-right px-4">
22
- <template v-if="!authenticated">
23
- <a
24
- class="dropdown-item"
25
- href="/sso/login"
26
- >
27
- {{ $t('Login') }}
28
- </a>
23
+ <template v-if="!authenticated">
24
+ <a
25
+ class="octopus-dropdown-item"
26
+ href="/sso/login"
27
+ >
28
+ {{ $t('Login') }}
29
+ </a>
30
+ <router-link
31
+ v-if="!isPodcastmaker"
32
+ class="octopus-dropdown-item"
33
+ to="/main/pub/create"
34
+ >
35
+ {{ $t('Create an account') }}
36
+ </router-link>
37
+ </template>
38
+ <template v-else>
39
+ <template
40
+ v-for="routerBack in routerBackoffice"
41
+ :key="routerBack.path"
42
+ >
29
43
  <router-link
30
- v-if="!isPodcastmaker"
31
- class="dropdown-item"
32
- to="/main/pub/create"
44
+ v-if="!isPodcastmaker && routerBack.condition"
45
+ :class="routerBack.class"
46
+ :to="routerBack.path"
33
47
  >
34
- {{ $t('Create an account') }}
48
+ {{ routerBack.title }}
35
49
  </router-link>
36
50
  </template>
37
- <template v-else>
51
+ <template v-if="!isEducation">
52
+ <hr>
38
53
  <template
39
- v-for="routerBack in routerBackoffice"
40
- :key="routerBack.path"
54
+ v-for="helpLink in helpLinks"
55
+ :key="helpLink.title"
41
56
  >
42
- <router-link
43
- v-if="!isPodcastmaker && routerBack.condition"
44
- :class="routerBack.class"
45
- :to="routerBack.path"
57
+ <a
58
+ :href="helpLink.href"
59
+ class="octopus-dropdown-item"
60
+ rel="noopener"
61
+ target="_blank"
46
62
  >
47
- {{ routerBack.title }}
48
- </router-link>
63
+ {{ helpLink.title }}
64
+ </a>
49
65
  </template>
50
- <template v-if="!isEducation">
51
- <hr class="dropdown-divider">
52
- <template
53
- v-for="helpLink in helpLinks"
54
- :key="helpLink.title"
55
- >
56
- <a
57
- :href="helpLink.href"
58
- class="dropdown-item"
59
- rel="noopener"
60
- target="_blank"
61
- >
62
- {{ helpLink.title }}
63
- </a>
64
- </template>
65
- </template>
66
- <hr class="dropdown-divider">
67
- <a
68
- class="dropdown-item"
69
- href="/sso/logout"
70
- >
71
- {{ $t('Logout') }}
72
- </a>
73
66
  </template>
74
- <router-link
75
- class="dropdown-item"
76
- to="/main/pub/contact"
67
+ <hr>
68
+ <a
69
+ class="octopus-dropdown-item"
70
+ href="/sso/logout"
77
71
  >
78
- {{ $t('Contact') }}
79
- </router-link>
80
- </div>
81
- </div>
72
+ {{ $t('Logout') }}
73
+ </a>
74
+ </template>
75
+ <router-link
76
+ class="octopus-dropdown-item"
77
+ to="/main/pub/contact"
78
+ >
79
+ {{ $t('Contact') }}
80
+ </router-link>
81
+ </Popover>
82
82
  </div>
83
83
  </template>
84
84
 
85
85
  <script lang="ts">
86
86
  import { state } from '../../store/paramStore';
87
-
87
+ import Popover from '../misc/Popover.vue';
88
88
  import { defineComponent } from 'vue'
89
89
  import { Organisation } from '@/store/class/general/organisation';
90
90
  export default defineComponent({
91
91
  name: 'HomeDropdown',
92
+ components:{
93
+ Popover
94
+ },
92
95
  props: {
93
96
  isEducation: { default: false, type: Boolean},
94
97
  },
@@ -104,9 +107,9 @@ export default defineComponent({
104
107
  routerBackoffice(){
105
108
  return [
106
109
  {title:this.$t('Upload'),class:"btn btn-primary w-100", path:'/main/priv/upload', condition: (state.generalParameters.isContribution as boolean)},
107
- {title:this.$t('My space'),class:"show-phone dropdown-item", path:'/main/priv/backoffice', condition: true},
108
- {title:this.$t('Edit my profile'),class:"dropdown-item", path:'/main/priv/edit/profile', condition: true},
109
- {title:this.$t('Edit my organisation'),class:"dropdown-item", path:'/main/priv/edit/organisation', condition: (state.generalParameters.isOrganisation as boolean) || 1<this.organisationsAvailable.length}];
110
+ {title:this.$t('My space'),class:"show-phone octopus-dropdown-item", path:'/main/priv/backoffice', condition: true},
111
+ {title:this.$t('Edit my profile'),class:"octopus-dropdown-item", path:'/main/priv/edit/profile', condition: true},
112
+ {title:this.$t('Edit my organisation'),class:"octopus-dropdown-item", path:'/main/priv/edit/organisation', condition: (state.generalParameters.isOrganisation as boolean) || 1<this.organisationsAvailable.length}];
110
113
  },
111
114
 
112
115
  isPodcastmaker(): boolean {
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <ul class="octopus-nav">
3
+ <li
4
+ v-for="index in tabNumber"
5
+ v-show="hasSlot(index-1)"
6
+ :key="index-1"
7
+ class="octopus-nav-item"
8
+ >
9
+ <div
10
+ class="octopus-nav-link"
11
+ :class="activeTab === (index-1)? 'active':''"
12
+ @click="$emit('update:activeTab',(index-1))"
13
+ >
14
+ <slot :name="(index-1)" />
15
+ </div>
16
+ </li>
17
+ </ul>
18
+ <div :class="transparent? 'd-flex flex-grow-1':'octopus-tab-content'">
19
+ <div
20
+ v-for="index in tabNumber"
21
+ v-show="hasSlot('tab'+(index-1))"
22
+ :key="index-1"
23
+ class="octopus-tab-pane"
24
+ :class="activeTab === (index-1)? 'active':''"
25
+ >
26
+ <slot :name="'tab'+(index-1)" />
27
+ </div>
28
+ </div>
29
+ </template>
30
+
31
+ <script lang="ts">
32
+ import { defineComponent } from 'vue'
33
+ export default defineComponent({
34
+ name: 'Nav',
35
+ props: {
36
+ tabNumber: { default: 0, type: Number},
37
+ activeTab: { default: 0, type: Number},
38
+ transparent:{ default: false, type: Boolean},
39
+ },
40
+ emits:['update:activeTab'],
41
+ methods:{
42
+ hasSlot(name = 'default') {
43
+ return !!this.$slots[ name ];
44
+ }
45
+ }
46
+ })
47
+ </script>
48
+
49
+ <style lang="scss">
50
+ @import '@scss/_variables.scss';
51
+ .octopus-app{
52
+ .octopus-nav{
53
+ display: flex;
54
+ flex-wrap: wrap;
55
+ padding-left: 0;
56
+ margin-bottom: 0;
57
+ margin-top: 0;
58
+ list-style: none;
59
+ border-bottom: 0.05rem solid #ddd;
60
+ }
61
+ .octopus-nav-item{
62
+ border-right: solid 1px rgb(222,226,230);
63
+ border-left: solid 1px rgb(222,226,230);
64
+ border-top: solid 1px rgb(222,226,230);
65
+ border-top-left-radius: 0.25rem;
66
+ border-top-right-radius: 0.25rem;
67
+ cursor: pointer;
68
+ flex-grow: 1;
69
+ text-align: center;
70
+ }
71
+ .octopus-nav-link{
72
+ display: block;
73
+ padding: 0.5rem 1rem;
74
+ text-decoration: none;
75
+ transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out;
76
+ border: 0.1rem solid transparent;
77
+ &:hover,&.active{
78
+ border-color: #dee2e6;
79
+ border-bottom-color: $octopus-primary-color;
80
+ color: $octopus-primary-color;
81
+ }
82
+ }
83
+ .octopus-tab-content{
84
+ border-right: solid 1px rgb(222,226,230);
85
+ border-left: solid 1px rgb(222,226,230);
86
+ border-bottom: solid 1px rgb(222,226,230);
87
+ background-color: #f8fafc;
88
+ }
89
+ .octopus-tab-pane{
90
+ display: none;
91
+ &.active{
92
+ display: flex;
93
+ justify-content: space-between;
94
+ padding: 0.5rem;
95
+ flex-grow: 1;
96
+ }
97
+ }
98
+ }
99
+ </style>
@@ -1,122 +1,163 @@
1
1
  <template>
2
- <div
3
- :id="id"
4
- ref="element"
5
- class="popover"
6
- role="tooltip"
7
- tabindex="-1"
2
+ <div
3
+ v-show="show && !disable"
4
+ :id="'popover'+target"
5
+ ref="popover"
6
+ tabindex="0"
7
+ class="octopus-popover"
8
+ :class="onlyClick?'octopus-dropdown':''"
9
+ :style="positionInlineStyle"
10
+ @blur="clearDataBlur"
8
11
  >
9
- <div ref="titleRef">
10
- <slot name="title">
11
- {{ title }}
12
- </slot>
12
+ <div
13
+ v-if="title"
14
+ class="bg-secondary p-2"
15
+ >
16
+ {{ title }}
13
17
  </div>
14
- <div ref="contentRef">
15
- <slot>
16
- {{ content }}
17
- </slot>
18
+ <div class="p-2">
19
+ <slot>{{ content }}</slot>
18
20
  </div>
19
21
  </div>
20
22
  </template>
21
23
 
22
24
  <script lang="ts">
23
- import {Popover} from 'bootstrap'
24
- import {defineComponent, onMounted, PropType, ref} from 'vue'
25
- import useEventListener from '../../helper/useEventListener'
25
+ import {defineComponent} from 'vue';
26
26
  export default defineComponent({
27
27
  name: 'Popover',
28
- props: {
28
+ props: {
29
29
  content: {type: String, default: ''},
30
- id: {type: String, default: ''},
31
- noninteractive: {type: Boolean, default: false},
32
- placement: {type: String as PropType<Popover.Options['placement']>, default: 'right'},
30
+ title: {type: String, default: ''},
33
31
  target: {type: String, required: true},
34
- title: {type: String, default: ''},
35
- show: {type: Boolean, default: false},
36
32
  disable: {type: Boolean, default: false},
33
+ onlyClick: {type: Boolean, default: false},
34
+ isFixed: {type: Boolean, default: false},
35
+ leftPos: {type: Boolean, default: false},
37
36
  },
38
- emits: ['show', 'shown', 'hide', 'hidden', 'inserted'],
39
- setup(props, {emit}) {
40
- const element = ref<HTMLElement>()
41
- const target = ref<HTMLElement>()
42
- const instance = ref<Popover>()
43
- const titleRef = ref<HTMLElement>()
44
- const contentRef = ref<HTMLElement>()
45
- function initPopover(){
46
- instance.value = new Popover(`#${props.target}`, {
47
- container: 'body',
48
- trigger: "hover focus",
49
- placement: props.placement,
50
- title: titleRef.value?.innerHTML || '',
51
- content: contentRef.value?.innerHTML || '',
52
- html: true,
53
- })
54
- if (document.getElementById(props.target)) {
55
- target.value = document.getElementById(props.target) as HTMLElement
56
- }
57
- element.value?.parentNode?.removeChild(element.value)
58
- if (props.show) {
59
- instance.value.show()
60
- }
61
- if (props.disable) {
62
- instance.value.disable()
63
- }
64
- }
65
- onMounted(()=>{
66
- initPopover();
67
- })
68
- useEventListener(target, 'show.bs.popover', () => emit('show'))
69
- useEventListener(target, 'shown.bs.popover', () => emit('shown'))
70
- useEventListener(target, 'hide.bs.popover', () => emit('hide'))
71
- useEventListener(target, 'hidden.bs.popover', () => emit('hidden'))
72
- useEventListener(target, 'inserted.bs.popover', () => emit('inserted'))
37
+ data () {
73
38
  return {
74
- element,
75
- titleRef,
76
- contentRef,
77
- instance,
78
- initPopover
39
+ show: false as boolean,
40
+ isClick: false as boolean,
41
+ posX: 0 as number,
42
+ posY: 0 as number,
43
+ targetElement: null as HTMLElement|null,
44
+ }
45
+ },
46
+ computed: {
47
+ popoverId(): string{
48
+ return 'popover'+this.target;
49
+ },
50
+ positionInlineStyle(): string {
51
+ return `left: ${this.posX}px; top: ${this.posY}px;`;
79
52
  }
80
53
  },
81
- watch:{
82
- disable(){
83
- if(!this.instance){ return; }
84
- if (this.disable) {
85
- this.instance.disable();
86
- } else {
87
- this.instance.enable();
88
- }
54
+ mounted () {
55
+ this.init();
56
+ },
57
+ unmounted(){
58
+ this.removeListeners();
59
+ },
60
+ methods: {
61
+ init () {
62
+ this.targetElement = document.getElementById(this.target);
63
+ if(this.targetElement){
64
+ if(!this.onlyClick){
65
+ this.targetElement.addEventListener("mouseenter", this.setPopoverData);
66
+ this.targetElement.addEventListener("mouseleave", this.clearData);
67
+ }
68
+ this.targetElement.addEventListener("click", this.setPopoverData);
69
+ this.targetElement.addEventListener("blur", this.clearDataBlur);
70
+ }
89
71
  },
90
- content(){
91
- if(!this.instance){ return; }
92
- this.$nextTick(() => {
93
- this.instance?.dispose();
94
- this.initPopover();
95
- });
72
+ removeListeners () {
73
+ if(this.targetElement){
74
+ if(!this.onlyClick){
75
+ this.targetElement.removeEventListener("mouseenter", this.setPopoverData);
76
+ this.targetElement.removeEventListener("mouseleave", this.clearData);
77
+ }
78
+ this.targetElement.removeEventListener("click", this.setPopoverData);
79
+ this.targetElement.addEventListener("blur", this.clearDataBlur);
80
+ }
96
81
  },
97
- title(){
98
- if(!this.instance){ return; }
99
- this.$nextTick(() => {
100
- this.instance?.dispose();
101
- this.initPopover();
102
- });
82
+ setPopoverData (e: MouseEvent|PointerEvent) {
83
+ if(this.disable){
84
+ return;
85
+ }
86
+ if(e && e.target){
87
+ if("click"===e.type){
88
+ if(this.show && this.isClick){
89
+ this.isClick = false;
90
+ this.clearData();
91
+ return;
92
+ }
93
+ this.isClick = true;
94
+ }
95
+ this.show = true;
96
+ const rectElement = (e.target as HTMLElement).getBoundingClientRect();
97
+ (this.$refs.popover as HTMLElement).style.display = 'block';
98
+ this.posX = this.leftPos? rectElement.right - (this.$refs.popover as HTMLElement).clientWidth : rectElement.left;
99
+ this.posY = rectElement.bottom + (this.isFixed ? 0 : window.scrollY)+ 5;
100
+ }
101
+ },
102
+ clearDataBlur (e: FocusEvent) {
103
+ if(e.relatedTarget){
104
+ const myElement = e.relatedTarget as HTMLElement;
105
+ if(this.popoverId===myElement.id){return;}
106
+ const parent = this.$refs.popover as HTMLElement;
107
+ if (null!==parent && parent.contains(myElement)) {
108
+ if(null!==myElement.classList && myElement.classList.contains('octopus-dropdown-item')){
109
+ this.$nextTick(() => {
110
+ this.isClick = false;
111
+ this.clearData();
112
+ });
113
+ }
114
+ return;
115
+ }
116
+ }
117
+ this.isClick = false;
118
+ this.clearData();
119
+ },
120
+ clearData () {
121
+ if(this.isClick){
122
+ return;
123
+ }
124
+ this.show = false;
125
+ this.posX = 0;
126
+ this.posY = 0;
103
127
  }
104
- }
105
-
106
- })
128
+ },
129
+ });
107
130
  </script>
108
131
  <style lang="scss">
109
- .popover{
110
- max-height: 80vh;
111
- max-width: 50vw !important;
112
- display: flex !important;
113
- flex-direction: column;
114
- hr{
115
- width: 100px;
116
- }
117
- .popover-body{
118
- overflow: auto;
119
- height: 100%;
120
- }
132
+ .octopus-popover{
133
+ background: white;
134
+ border: 1px solid #ccc;
135
+ border-radius: 5px;
136
+ position: absolute;
137
+ z-index: 9999;
138
+ &.octopus-dropdown{
139
+ min-width: 200px;
140
+ padding: 0.5rem 1rem;
141
+ .octopus-dropdown-item{
142
+ display: block;
143
+ color: rgb(29, 29, 29);
144
+ width: 100%;
145
+ padding: 0.25rem 1rem;
146
+ font-weight: 400;
147
+ text-decoration: none;
148
+ white-space: nowrap;
149
+ background-color: transparent;
150
+ border: 0;
151
+ &:hover{
152
+ background: rgb(243, 243, 243);
153
+ }
154
+ }
155
+ hr{
156
+ margin: 0.5rem 0;
157
+ overflow: hidden;
158
+ border-top: 1px solid #ccc;
159
+ opacity: 1;
160
+ }
161
+ }
121
162
  }
122
163
  </style>
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <div
3
+ class="octopus-progress"
4
+ >
5
+ <div
6
+ v-if="secondaryProgress"
7
+ class="octopus-progress-bar bg-light"
8
+ role="progressbar"
9
+ aria-valuenow="0"
10
+ aria-valuemin="0"
11
+ aria-valuemax="100"
12
+ :style="'width: ' + secondaryProgress + '%'"
13
+ />
14
+ <div
15
+ class="octopus-progress-bar bg-primary"
16
+ role="progressbar"
17
+ aria-valuenow="0"
18
+ aria-valuemin="0"
19
+ aria-valuemax="100"
20
+ :style="'width: ' + mainProgress + '%'"
21
+ />
22
+ <div
23
+ v-if="alertBar"
24
+ class="octopus-progress-bar octopus-progress-bar-duration bg-danger"
25
+ :style="'left: ' + alertBar + '%'"
26
+ />
27
+ <div
28
+ v-if="isProgressCursor"
29
+ class="progress-bar-cursor"
30
+ :style="'left:' + mainProgress + '%'"
31
+ />
32
+ </div>
33
+ </template>
34
+
35
+ <script lang="ts">
36
+ import { defineComponent } from 'vue';
37
+ export default defineComponent({
38
+ name: 'ProgressBar',
39
+ props: {
40
+ alertBar: { default: undefined, type: Number},
41
+ mainProgress: { default: 0, type: Number},
42
+ secondaryProgress: { default: 0, type: Number},
43
+ isProgressCursor: { default: false, type: Boolean},
44
+ },
45
+ })
46
+ </script>
47
+
48
+ <style lang="scss">
49
+ @import '@scss/_variables.scss';
50
+ .octopus-app{
51
+ .octopus-progress{
52
+ display: flex;
53
+ overflow: hidden;
54
+ background-color:#e9ecef;
55
+ border-radius: 0.375rem;
56
+ position: relative;
57
+ cursor: pointer;
58
+
59
+ .octopus-progress-bar{
60
+ position: absolute;
61
+ display: flex;
62
+ flex-direction: column;
63
+ justify-content: center;
64
+ overflow: hidden;
65
+ color: white;
66
+ text-align: center;
67
+ white-space: nowrap;
68
+ background-color: $octopus-primary-color;
69
+ transition: width 0.6s ease;
70
+ }
71
+ &,.octopus-progress-bar{
72
+ height: 4px;
73
+ @media (max-width: 960px) {
74
+ height: 8px;
75
+ }
76
+ }
77
+ &.large,&.large .octopus-progress-bar{
78
+ height: 15px;
79
+ }
80
+ &.medium,&.medium .octopus-progress-bar{
81
+ height: 6px;
82
+ }
83
+ .octopus-progress-bar-duration {
84
+ width: 10px;
85
+ }
86
+ .octopus-progress-bar-cursor{
87
+ width: 10px;
88
+ height: 10px;
89
+ border-radius: 50%;
90
+ background: black;
91
+ align-self: center;
92
+ position: absolute;
93
+ }
94
+ }
95
+ }
96
+ </style>
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <div
3
+ class="octopus-spinner"
4
+ :class="small?'small':''"
5
+ />
6
+ </template>
7
+
8
+ <script lang="ts">
9
+ import { defineComponent } from 'vue';
10
+ export default defineComponent({
11
+ name: "Spinner",
12
+ props: {
13
+ small: { default: false, type: Boolean },
14
+ },
15
+ })
16
+ </script>
17
+ <style lang="scss">
18
+ .octopus-app .octopus-spinner{
19
+ display: inline-block;
20
+ width:2rem;
21
+ height:2rem;
22
+ border-radius: 50%;
23
+ animation: 0.75s linear infinite spinner-border;
24
+ border: 2px solid currentcolor;
25
+ border-right-color: transparent;
26
+ flex-shrink: 0;
27
+
28
+ &.small{
29
+ width:1rem;
30
+ height:1rem;
31
+ }
32
+
33
+ @keyframes spinner-border {
34
+ to { transform: rotate(360deg); }
35
+ }
36
+ }
37
+ </style>
@@ -53,7 +53,7 @@
53
53
  />
54
54
  <div class="d-flex flex-column">
55
55
  <div class="hosted-by">
56
- {{ $t('Hosted by') }}<span class="ms-1 me-1 primary-darker">Saooti</span>
56
+ {{ $t('Hosted by') }}<span class="ms-1 me-1 text-primary">Saooti</span>
57
57
  </div>
58
58
  <div class="d-flex justify-content-end flex-nowrap">
59
59
  <HomeDropdown :is-education="isEducation" />