mirror of
https://github.com/mattermost/focalboard.git
synced 2024-12-24 13:43:12 +02:00
* Made confirmationDialogBox from existing dialog component * Used ConfirmationDialogBox to raise warning before deletion of card property * fixes as ci checks did not pass * fixes to pass ci tests * Flash Message now visible (changed its z-index) * Confirmation Dialog shows the property name. * fixes for eslint test failure * fixes for eslint test fail * fixes for eslint test failure * fix for eslint test failure * fixed a wrong subtext string * fixed eslint issues in scss * i18n en.json for localisation updated * `en.json;`-wrong file generated by `npm run i18n-extract ` command removed Co-authored-by: Prakhar <>
This commit is contained in:
parent
a756b7e1c6
commit
977bc1dafa
@ -14,6 +14,9 @@
|
|||||||
"CardDetail.addCardText": "add card text",
|
"CardDetail.addCardText": "add card text",
|
||||||
"CardDetail.moveContent": "move card content",
|
"CardDetail.moveContent": "move card content",
|
||||||
"CardDetail.new-comment-placeholder": "Add a comment...",
|
"CardDetail.new-comment-placeholder": "Add a comment...",
|
||||||
|
"CardDetailProperty.confirm-delete": "Confirm Delete Property",
|
||||||
|
"CardDetailProperty.confirm-delete-subtext": "Are you sure you want to delete the property \"{propertyName}\"? Deleting it will delete the property from all cards in this board.",
|
||||||
|
"CardDetailProperty.property-deleted": "Deleted {propertyName} Successfully!",
|
||||||
"CardDialog.editing-template": "You're editing a template.",
|
"CardDialog.editing-template": "You're editing a template.",
|
||||||
"CardDialog.nocard": "This card doesn't exist or is inaccessible.",
|
"CardDialog.nocard": "This card doesn't exist or is inaccessible.",
|
||||||
"CardDialog.copiedLink": "Copied!",
|
"CardDialog.copiedLink": "Copied!",
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React from 'react'
|
|
||||||
import {FormattedMessage} from 'react-intl'
|
import React, {useState} from 'react'
|
||||||
|
import {useIntl, FormattedMessage} from 'react-intl'
|
||||||
|
|
||||||
import {Board, PropertyType, IPropertyTemplate} from '../../blocks/board'
|
import {Board, PropertyType, IPropertyTemplate} from '../../blocks/board'
|
||||||
import {Card} from '../../blocks/card'
|
import {Card} from '../../blocks/card'
|
||||||
@ -14,6 +15,8 @@ import MenuWrapper from '../../widgets/menuWrapper'
|
|||||||
import PropertyMenu from '../../widgets/propertyMenu'
|
import PropertyMenu from '../../widgets/propertyMenu'
|
||||||
|
|
||||||
import PropertyValueElement from '../propertyValueElement'
|
import PropertyValueElement from '../propertyValueElement'
|
||||||
|
import {ConfirmationDialogBox} from '../confirmationDialogBox'
|
||||||
|
import {sendFlashMessage} from '../flashMessages'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
board: Board
|
board: Board
|
||||||
@ -27,8 +30,13 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CardDetailProperties = React.memo((props: Props) => {
|
const CardDetailProperties = React.memo((props: Props) => {
|
||||||
|
const intl = useIntl()
|
||||||
const {board, card, cards, views, activeView, contents, comments} = props
|
const {board, card, cards, views, activeView, contents, comments} = props
|
||||||
|
|
||||||
|
const [showConfirmationDialog, setShowConfirmationDialog] = useState<boolean>(false)
|
||||||
|
const [deletingPropId, setDeletingPropId] = useState<string>('')
|
||||||
|
const [deletingPropName, setDeletingPropName] = useState<string>('')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='octo-propertylist CardDetailProperties'>
|
<div className='octo-propertylist CardDetailProperties'>
|
||||||
{board.fields.cardProperties.map((propertyTemplate: IPropertyTemplate) => {
|
{board.fields.cardProperties.map((propertyTemplate: IPropertyTemplate) => {
|
||||||
@ -47,7 +55,12 @@ const CardDetailProperties = React.memo((props: Props) => {
|
|||||||
propertyName={propertyTemplate.name}
|
propertyName={propertyTemplate.name}
|
||||||
propertyType={propertyTemplate.type}
|
propertyType={propertyTemplate.type}
|
||||||
onTypeAndNameChanged={(newType: PropertyType, newName: string) => mutator.changePropertyTypeAndName(board, cards, propertyTemplate, newType, newName)}
|
onTypeAndNameChanged={(newType: PropertyType, newName: string) => mutator.changePropertyTypeAndName(board, cards, propertyTemplate, newType, newName)}
|
||||||
onDelete={(id: string) => mutator.deleteProperty(board, views, cards, id)}
|
onDelete={(id: string) => {
|
||||||
|
setDeletingPropId(id)
|
||||||
|
setDeletingPropName(propertyTemplate.name)
|
||||||
|
setShowConfirmationDialog(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</MenuWrapper>
|
</MenuWrapper>
|
||||||
}
|
}
|
||||||
@ -64,6 +77,26 @@ const CardDetailProperties = React.memo((props: Props) => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{showConfirmationDialog && (
|
||||||
|
<ConfirmationDialogBox
|
||||||
|
propertyId={deletingPropId}
|
||||||
|
onClose={() => setShowConfirmationDialog(false)}
|
||||||
|
onConfirm={() => {
|
||||||
|
mutator.deleteProperty(board, views, cards, deletingPropId)
|
||||||
|
setShowConfirmationDialog(false)
|
||||||
|
sendFlashMessage({content: intl.formatMessage({id: 'CardDetailProperty.property-deleted', defaultMessage: 'Deleted {propertyName} Successfully!'}, {propertyName: deletingPropName}), severity: 'high'})
|
||||||
|
}}
|
||||||
|
|
||||||
|
heading={intl.formatMessage({id: 'CardDetailProperty.confirm-delete', defaultMessage: 'Confirm Delete Property'})}
|
||||||
|
subText={intl.formatMessage({
|
||||||
|
id: 'CardDetailProperty.confirm-delete-subtext',
|
||||||
|
defaultMessage: 'Are you sure you want to delete the property "{propertyName}"? Deleting it will delete the property from all cards in this board.',
|
||||||
|
},
|
||||||
|
{propertyName: deletingPropName})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{!props.readonly &&
|
{!props.readonly &&
|
||||||
<div className='octo-propertyname add-property'>
|
<div className='octo-propertyname add-property'>
|
||||||
<Button
|
<Button
|
||||||
|
60
webapp/src/components/confirmationDialogBox.scss
Normal file
60
webapp/src/components/confirmationDialogBox.scss
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
.confirmation-dialog-box {
|
||||||
|
.dialog {
|
||||||
|
position: fixed;
|
||||||
|
top: 30%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: max-content;
|
||||||
|
height: max-content;
|
||||||
|
z-index: 300;
|
||||||
|
|
||||||
|
background-color: rgb(var(--center-channel-bg-rgb));
|
||||||
|
box-shadow: rgba(var(--center-channel-color-rgb), 0.1) 0 0 0 1px,
|
||||||
|
rgba(var(--center-channel-color-rgb), 0.1) 0 2px 4px;
|
||||||
|
|
||||||
|
border-radius: var(--modal-rad);
|
||||||
|
padding: 0;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
> .toolbar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-area {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-text {
|
||||||
|
width: 26rem;
|
||||||
|
word-wrap: normal;
|
||||||
|
margin: 0.5rem 3rem;
|
||||||
|
padding: 2px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 400px) {
|
||||||
|
width: 12rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
margin: 1rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.Button {
|
||||||
|
margin: 2px 1rem;
|
||||||
|
}
|
||||||
|
}
|
56
webapp/src/components/confirmationDialogBox.tsx
Normal file
56
webapp/src/components/confirmationDialogBox.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import {FormattedMessage} from 'react-intl'
|
||||||
|
|
||||||
|
import Button from '../widgets/buttons/button'
|
||||||
|
|
||||||
|
import Dialog from './dialog'
|
||||||
|
import './confirmationDialogBox.scss'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
propertyId: string;
|
||||||
|
onClose: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
heading: string;
|
||||||
|
subText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConfirmationDialogBox = (props: Props) => {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
className='confirmation-dialog-box'
|
||||||
|
onClose={props.onClose}
|
||||||
|
>
|
||||||
|
<div className='box-area'>
|
||||||
|
<h3 className='heading'>{props.heading}</h3>
|
||||||
|
<p className='sub-text'>{props.subText}</p>
|
||||||
|
|
||||||
|
<div className='action-buttons'>
|
||||||
|
<Button
|
||||||
|
title='Cancel'
|
||||||
|
active={true}
|
||||||
|
onClick={props.onClose}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='ConfirmationDialog.cancel-action'
|
||||||
|
defaultMessage='Cancel'
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
title='Delete'
|
||||||
|
submit={true}
|
||||||
|
emphasis='danger'
|
||||||
|
onClick={props.onConfirm}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='ConfirmationDialog.delete-action'
|
||||||
|
defaultMessage='Delete'
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
@ -12,7 +12,7 @@ import './dialog.scss'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
toolsMenu: React.ReactNode
|
toolsMenu?: React.ReactNode // some dialogs may not require a toolmenu
|
||||||
hideCloseButton?: boolean
|
hideCloseButton?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
onClose: () => void,
|
onClose: () => void,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
z-index: 12;
|
z-index: 999;
|
||||||
|
|
||||||
&.flashIn {
|
&.flashIn {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
--sidebar-text-rgb: 255, 255, 255;
|
--sidebar-text-rgb: 255, 255, 255;
|
||||||
--button-color-rgb: 255, 255, 255;
|
--button-color-rgb: 255, 255, 255;
|
||||||
--button-bg-rgb: 28, 88, 217;
|
--button-bg-rgb: 28, 88, 217;
|
||||||
|
--button-danger-color-rgb: 255, 255, 255;
|
||||||
|
--button-danger-bg-rgb: 210, 75, 78;
|
||||||
--link-color-rgb: 56, 111, 229;
|
--link-color-rgb: 56, 111, 229;
|
||||||
--error-text-rgb: #d24b4e;
|
--error-text-rgb: #d24b4e;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.emphasis--danger {
|
||||||
|
color: rgb(var(--button-danger-color-rgb));
|
||||||
|
background-color: rgb(var(--button-danger-bg-rgb));
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(var(--button-danger-bg-rgb), 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background: rgba(var(--button-bg-rgb), 0.08);
|
background: rgba(var(--button-bg-rgb), 0.08);
|
||||||
color: rgb(var(--button-bg-rgb));
|
color: rgb(var(--button-bg-rgb));
|
||||||
|
Loading…
Reference in New Issue
Block a user