mirror of
https://github.com/nextcloud/server.git
synced 2026-06-13 18:50:47 -04:00
Merge pull request #53850 from nextcloud/feat/noid/add-busy-status
This commit is contained in:
commit
1675aa4f45
17 changed files with 103 additions and 55 deletions
|
|
@ -141,7 +141,7 @@ class StatusService {
|
|||
$this->logger->debug("Found $count applicable event(s), changing user status", ['user' => $userId]);
|
||||
$this->userStatusService->setUserStatus(
|
||||
$userId,
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::BUSY,
|
||||
IUserStatus::MESSAGE_CALENDAR_BUSY,
|
||||
true
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use OCP\UserStatus\IUserStatus;
|
|||
* @package OCA\UserStatus\Service
|
||||
*/
|
||||
class PredefinedStatusService {
|
||||
private const BE_RIGHT_BACK = 'be-right-back';
|
||||
private const MEETING = 'meeting';
|
||||
private const COMMUTING = 'commuting';
|
||||
private const SICK_LEAVE = 'sick-leave';
|
||||
|
|
@ -64,6 +65,15 @@ class PredefinedStatusService {
|
|||
'time' => 1800,
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => self::BE_RIGHT_BACK,
|
||||
'icon' => '⏳',
|
||||
'message' => $this->getTranslatedStatusForId(self::BE_RIGHT_BACK),
|
||||
'clearAt' => [
|
||||
'type' => 'period',
|
||||
'time' => 900,
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => self::REMOTE_WORK,
|
||||
'icon' => '🏡',
|
||||
|
|
@ -143,6 +153,9 @@ class PredefinedStatusService {
|
|||
case self::REMOTE_WORK:
|
||||
return '🏡';
|
||||
|
||||
case self::BE_RIGHT_BACK:
|
||||
return '⏳';
|
||||
|
||||
case self::CALL:
|
||||
return '💬';
|
||||
|
||||
|
|
@ -179,6 +192,9 @@ class PredefinedStatusService {
|
|||
case self::CALL:
|
||||
return $this->l10n->t('In a call');
|
||||
|
||||
case self::BE_RIGHT_BACK:
|
||||
return $this->l10n->t('Be right back');
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
@ -195,6 +211,7 @@ class PredefinedStatusService {
|
|||
self::SICK_LEAVE,
|
||||
self::VACATIONING,
|
||||
self::OUT_OF_OFFICE,
|
||||
self::BE_RIGHT_BACK,
|
||||
self::REMOTE_WORK,
|
||||
IUserStatus::MESSAGE_CALL,
|
||||
IUserStatus::MESSAGE_AVAILABILITY,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
:value="option"
|
||||
:clearable="false"
|
||||
placement="top"
|
||||
label-outside
|
||||
@option:selected="select" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -72,12 +73,9 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
.clear-at-select {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
gap: calc(2 * var(--default-grid-baseline));
|
||||
align-items: center;
|
||||
|
||||
&__label {
|
||||
margin-inline-end: 12px;
|
||||
}
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
|
||||
&__select {
|
||||
flex-grow: 1;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@
|
|||
name="user-status-online"
|
||||
@change="onChange">
|
||||
<label :for="id" class="user-status-online-select__label">
|
||||
{{ label }}
|
||||
<NcUserStatusIcon :status="type"
|
||||
class="user-status-online-select__icon"
|
||||
aria-hidden="true" />
|
||||
{{ label }}
|
||||
<em class="user-status-online-select__subline">{{ subline }}</em>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -63,45 +64,42 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use 'sass:math';
|
||||
$icon-size: 24px;
|
||||
$label-padding: 8px;
|
||||
|
||||
.user-status-online-select {
|
||||
&__label {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin: $label-padding;
|
||||
padding: $label-padding;
|
||||
padding-inline-start: $icon-size + $label-padding * 2;
|
||||
border: 2px solid var(--color-main-background);
|
||||
box-sizing: inherit;
|
||||
display: grid;
|
||||
grid-template-columns: var(--default-clickable-area) 1fr 2fr;
|
||||
align-items: center;
|
||||
gap: var(--default-grid-baseline);
|
||||
min-height: var(--default-clickable-area);
|
||||
padding: var(--default-grid-baseline);
|
||||
border-radius: var(--border-radius-large);
|
||||
background-color: var(--color-background-hover);
|
||||
background-position: $label-padding center;
|
||||
background-size: $icon-size;
|
||||
|
||||
span,
|
||||
& {
|
||||
&, & * {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
top: calc(50% - 10px);
|
||||
inset-inline-start: 10px;
|
||||
display: block;
|
||||
width: $icon-size;
|
||||
height: $icon-size;
|
||||
&:hover {
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
flex-shrink: 0;
|
||||
max-width: 34px;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
&__input:checked + &__label {
|
||||
outline: 2px solid var(--color-main-text);
|
||||
background-color: var(--color-background-dark);
|
||||
box-shadow: 0 0 0 4px var(--color-main-background);
|
||||
}
|
||||
|
||||
&__input:focus-visible + &__label {
|
||||
outline: 2px solid var(--color-primary-element) !important;
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
|
||||
&__subline {
|
||||
|
|
|
|||
|
|
@ -81,10 +81,19 @@ export default {
|
|||
flex-basis: 100%;
|
||||
border-radius: var(--border-radius);
|
||||
align-items: center;
|
||||
min-height: 44px;
|
||||
min-height: var(--default-clickable-area);
|
||||
padding-inline: var(--default-grid-baseline);
|
||||
|
||||
&, & * {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
|
||||
&--icon {
|
||||
flex-basis: 40px;
|
||||
flex-basis: var(--default-clickable-area);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -106,11 +115,13 @@ export default {
|
|||
&__label:active {
|
||||
outline: 2px solid var(--color-main-text);
|
||||
box-shadow: 0 0 0 4px var(--color-main-background);
|
||||
background-color: var(--color-background-dark);
|
||||
border-radius: var(--border-radius-large);
|
||||
}
|
||||
|
||||
&__input:focus-visible + &__label {
|
||||
outline: 2px solid var(--color-primary-element) !important;
|
||||
background-color: var(--color-background-dark);
|
||||
border-radius: var(--border-radius-large);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ export default {
|
|||
.predefined-statuses-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 10px;
|
||||
gap: var(--default-grid-baseline);
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ export default {
|
|||
flex-basis: 100%;
|
||||
border-radius: var(--border-radius);
|
||||
align-items: center;
|
||||
min-height: 44px;
|
||||
min-height: var(--default-clickable-area);
|
||||
padding-inline: var(--default-grid-baseline);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
|
|
@ -77,7 +78,7 @@ export default {
|
|||
}
|
||||
|
||||
&__icon {
|
||||
flex-basis: 40px;
|
||||
flex-basis: var(--default-clickable-area);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
<template>
|
||||
<NcModal size="normal"
|
||||
:name="$t('user_status', 'Set status')"
|
||||
aria-labelledby="user_status-set-dialog"
|
||||
label-id="user_status-set-dialog"
|
||||
dark
|
||||
:set-return-focus="setReturnFocus"
|
||||
@close="closeModal">
|
||||
<div class="set-status-modal">
|
||||
|
|
@ -336,6 +336,10 @@ export default {
|
|||
.set-status-modal {
|
||||
padding: 8px 20px 20px 20px;
|
||||
|
||||
&, & * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&__header {
|
||||
font-size: 21px;
|
||||
text-align: center;
|
||||
|
|
@ -343,12 +347,14 @@ export default {
|
|||
min-height: var(--default-clickable-area);
|
||||
line-height: var(--default-clickable-area);
|
||||
overflow-wrap: break-word;
|
||||
margin-block: 0 12px;
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
}
|
||||
|
||||
&__online-status {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(2 * var(--default-grid-baseline));
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
}
|
||||
|
||||
&__custom-input {
|
||||
|
|
@ -357,13 +363,14 @@ export default {
|
|||
align-items: center;
|
||||
gap: var(--default-grid-baseline);
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
padding-inline-start: var(--default-grid-baseline);
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
}
|
||||
|
||||
&__automation-hint {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
margin-block: 0 calc(2 * var(--default-grid-baseline));
|
||||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ const getAllStatusOptions = () => {
|
|||
}, {
|
||||
type: 'away',
|
||||
label: t('user_status', 'Away'),
|
||||
}, {
|
||||
type: 'busy',
|
||||
label: t('user_status', 'Busy'),
|
||||
}, {
|
||||
type: 'dnd',
|
||||
label: t('user_status', 'Do not disturb'),
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class StatusServiceIntegrationTest extends TestCase {
|
|||
);
|
||||
$this->service->setUserStatus(
|
||||
'test123',
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::BUSY,
|
||||
IUserStatus::MESSAGE_CALENDAR_BUSY,
|
||||
true,
|
||||
);
|
||||
|
|
@ -147,12 +147,12 @@ class StatusServiceIntegrationTest extends TestCase {
|
|||
|
||||
$this->service->setUserStatus(
|
||||
'test123',
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::BUSY,
|
||||
IUserStatus::MESSAGE_CALL,
|
||||
true,
|
||||
);
|
||||
self::assertSame(
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::BUSY,
|
||||
$this->service->findByUserId('test123')->getStatus(),
|
||||
);
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ class StatusServiceIntegrationTest extends TestCase {
|
|||
|
||||
$nostatus = $this->service->setUserStatus(
|
||||
'test123',
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::BUSY,
|
||||
IUserStatus::MESSAGE_CALENDAR_BUSY,
|
||||
true,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class PredefinedStatusServiceTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetDefaultStatuses(): void {
|
||||
$this->l10n->expects($this->exactly(7))
|
||||
$this->l10n->expects($this->exactly(8))
|
||||
->method('t')
|
||||
->willReturnCallback(function ($text, $parameters = []) {
|
||||
return vsprintf($text, $parameters);
|
||||
|
|
@ -52,6 +52,15 @@ class PredefinedStatusServiceTest extends TestCase {
|
|||
'time' => 1800,
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => 'be-right-back',
|
||||
'icon' => '⏳',
|
||||
'message' => 'Be right back',
|
||||
'clearAt' => [
|
||||
'type' => 'period',
|
||||
'time' => 900,
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => 'remote-work',
|
||||
'icon' => '🏡',
|
||||
|
|
@ -106,6 +115,7 @@ class PredefinedStatusServiceTest extends TestCase {
|
|||
['sick-leave', '🤒'],
|
||||
['vacationing', '🌴'],
|
||||
['remote-work', '🏡'],
|
||||
['be-right-back', '⏳'],
|
||||
['call', '💬'],
|
||||
['unknown-id', null],
|
||||
];
|
||||
|
|
@ -127,6 +137,7 @@ class PredefinedStatusServiceTest extends TestCase {
|
|||
['sick-leave', 'Out sick'],
|
||||
['vacationing', 'Vacationing'],
|
||||
['remote-work', 'Working remotely'],
|
||||
['be-right-back', 'Be right back'],
|
||||
['call', 'In a call'],
|
||||
['unknown-id', null],
|
||||
];
|
||||
|
|
@ -145,13 +156,14 @@ class PredefinedStatusServiceTest extends TestCase {
|
|||
['sick-leave', true],
|
||||
['vacationing', true],
|
||||
['remote-work', true],
|
||||
['be-right-back', true],
|
||||
['call', true],
|
||||
['unknown-id', false],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetDefaultStatusById(): void {
|
||||
$this->l10n->expects($this->exactly(7))
|
||||
$this->l10n->expects($this->exactly(8))
|
||||
->method('t')
|
||||
->willReturnCallback(function ($text, $parameters = []) {
|
||||
return vsprintf($text, $parameters);
|
||||
|
|
|
|||
4
dist/core-main.js
vendored
4
dist/core-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-main.js.map
vendored
2
dist/core-main.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/user-status-modal-5133.js
vendored
4
dist/user-status-modal-5133.js
vendored
File diff suppressed because one or more lines are too long
2
dist/user-status-modal-5133.js.map
vendored
2
dist/user-status-modal-5133.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/user_status-menu.js
vendored
4
dist/user_status-menu.js
vendored
File diff suppressed because one or more lines are too long
2
dist/user_status-menu.js.map
vendored
2
dist/user_status-menu.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue