From 4e55dc4ffbb5474f7a4c6dd03acdb8c1ca5d32e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Thu, 29 Oct 2020 18:44:56 +0100 Subject: [PATCH 1/8] Improving theming in icons for the sidebar --- webapp/src/components/sidebar.scss | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/src/components/sidebar.scss b/webapp/src/components/sidebar.scss index 966554d33..3f883cae9 100644 --- a/webapp/src/components/sidebar.scss +++ b/webapp/src/components/sidebar.scss @@ -90,4 +90,13 @@ cursor: pointer; flex-grow: 1; } + + .OptionsIcon, .SubmenuTriangleIcon, .DotIcon { + fill: rgba(var(--sidebar-fg), 0.5); + } + + .ShowSidebarIcon, .HamburgerIcon { + stroke: rgba(var(--sidebar-fg), 0.5); + stroke-width: 6px; + } } From 7629e09eee2b5fca6008fed5bf01bdde09bdaa5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Thu, 29 Oct 2020 18:48:51 +0100 Subject: [PATCH 2/8] Fix icon colors in the sidebar --- webapp/src/components/sidebar.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/components/sidebar.scss b/webapp/src/components/sidebar.scss index 3f883cae9..b64699198 100644 --- a/webapp/src/components/sidebar.scss +++ b/webapp/src/components/sidebar.scss @@ -95,7 +95,7 @@ fill: rgba(var(--sidebar-fg), 0.5); } - .ShowSidebarIcon, .HamburgerIcon { + .HideSidebarIcon { stroke: rgba(var(--sidebar-fg), 0.5); stroke-width: 6px; } From 238c7664a2ef2d6620ed375cdf53ba71cba75816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 07:47:39 +0100 Subject: [PATCH 3/8] Tiny detail fixed on sidebar theming --- webapp/src/widgets/menu/menu.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webapp/src/widgets/menu/menu.scss b/webapp/src/widgets/menu/menu.scss index 813ef315a..cc6cc45f9 100644 --- a/webapp/src/widgets/menu/menu.scss +++ b/webapp/src/widgets/menu/menu.scss @@ -43,5 +43,9 @@ .menu-name { flex-grow: 1; } + + .SubmenuTriangleIcon { + fill: rgba(var(--main-fg), 0.7); + } } } From dc89bfd6276617c2d678d85e06b53f7da8ee5c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 10:05:06 +0100 Subject: [PATCH 4/8] Adding button with menu component and using it for the new button --- webapp/src/components/viewHeader.tsx | 32 +++++++++++---- .../src/widgets/buttons/buttonWithMenu.scss | 40 +++++++++++++++++++ webapp/src/widgets/buttons/buttonWithMenu.tsx | 37 +++++++++++++++++ webapp/src/widgets/menu/labelOption.scss | 8 ++++ webapp/src/widgets/menu/labelOption.tsx | 21 ++++++++++ webapp/src/widgets/menu/menu.tsx | 2 + 6 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 webapp/src/widgets/buttons/buttonWithMenu.scss create mode 100644 webapp/src/widgets/buttons/buttonWithMenu.tsx create mode 100644 webapp/src/widgets/menu/labelOption.scss create mode 100644 webapp/src/widgets/menu/labelOption.tsx diff --git a/webapp/src/components/viewHeader.tsx b/webapp/src/components/viewHeader.tsx index 2999818c8..0381f15f2 100644 --- a/webapp/src/components/viewHeader.tsx +++ b/webapp/src/components/viewHeader.tsx @@ -21,11 +21,13 @@ import DropdownIcon from '../widgets/icons/dropdown' import OptionsIcon from '../widgets/icons/options' import SortUpIcon from '../widgets/icons/sortUp' import SortDownIcon from '../widgets/icons/sortDown' +import ButtonWithMenu from '../widgets/buttons/buttonWithMenu' import {Editable} from './editable' import FilterComponent from './filterComponent' import './viewHeader.scss' +import {sendFlashMessage} from './flashMessages' type Props = { boardTree?: BoardTree @@ -348,17 +350,33 @@ class ViewHeader extends React.Component { /> -
{ this.props.addCard(true) }} + text={( + + )} > - -
+ + + + + + + sendFlashMessage({content: 'Not implemented yet', severity: 'low'})} + /> + + ) } diff --git a/webapp/src/widgets/buttons/buttonWithMenu.scss b/webapp/src/widgets/buttons/buttonWithMenu.scss new file mode 100644 index 000000000..b420a66f7 --- /dev/null +++ b/webapp/src/widgets/buttons/buttonWithMenu.scss @@ -0,0 +1,40 @@ +.ButtonWithMenu.octo-button { + display: flex; + align-items: stretch; + text-align: center; + min-width: 20px; + cursor: pointer; + overflow: visible; + padding: 0; + + .button-text { + padding: 3px 10px; + background-color: rgb(var(--button-bg)); + color: rgb(var(--button-fg)); + border-radius: 5px 0 0 5px; + transition: background 100ms ease-out 0s; + height: 100%; + + &:hover { + background-color: rgba(var(--button-bg), 0.8); + } + } + + .button-dropdown { + background-color: rgb(var(--button-bg)); + border-left: 1px solid rgba(var(--button-fg), 0.2); + display: flex; + padding: 0 3px; + align-items: center; + border-radius: 0 5px 5px 0; + transition: background 100ms ease-out 0s; + height: 100%; + + &:hover { + background-color: rgba(var(--button-bg), 0.8); + } + .DropdownIcon { + stroke: rgb(var(--button-fg)); + } + } +} diff --git a/webapp/src/widgets/buttons/buttonWithMenu.tsx b/webapp/src/widgets/buttons/buttonWithMenu.tsx new file mode 100644 index 000000000..b48f80fbc --- /dev/null +++ b/webapp/src/widgets/buttons/buttonWithMenu.tsx @@ -0,0 +1,37 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react' + +import DropdownIcon from '../icons/dropdown' +import MenuWrapper from '../menuWrapper' + +import './buttonWithMenu.scss' + +type Props = { + onClick?: (e: React.MouseEvent) => void + children?: React.ReactNode + title?: string + text: React.ReactNode +} + +export default class ButtonWithMenu extends React.PureComponent { + public render(): JSX.Element { + return ( +
+
+ {this.props.text} +
+ +
+ +
+ {this.props.children} +
+
+ ) + } +} diff --git a/webapp/src/widgets/menu/labelOption.scss b/webapp/src/widgets/menu/labelOption.scss new file mode 100644 index 000000000..c539209a7 --- /dev/null +++ b/webapp/src/widgets/menu/labelOption.scss @@ -0,0 +1,8 @@ +.Menu { + .LabelOption.menu-option { + cursor: auto; + &:hover { + background: inherit; + } + } +} diff --git a/webapp/src/widgets/menu/labelOption.tsx b/webapp/src/widgets/menu/labelOption.tsx new file mode 100644 index 000000000..610a3c819 --- /dev/null +++ b/webapp/src/widgets/menu/labelOption.tsx @@ -0,0 +1,21 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react' + +import './labelOption.scss' + +type LabelOptionProps = { + icon?: string + children: React.ReactNode +} + +export default class LabelOption extends React.PureComponent { + public render(): JSX.Element { + return ( +
+
{this.props.children}
+ {this.props.icon} +
+ ) + } +} diff --git a/webapp/src/widgets/menu/menu.tsx b/webapp/src/widgets/menu/menu.tsx index 8b7172e53..3cd6a9f60 100644 --- a/webapp/src/widgets/menu/menu.tsx +++ b/webapp/src/widgets/menu/menu.tsx @@ -7,6 +7,7 @@ import SwitchOption from './switchOption' import TextOption from './textOption' import ColorOption from './colorOption' import SubMenuOption from './subMenuOption' +import LabelOption from './labelOption' import './menu.scss' @@ -21,6 +22,7 @@ export default class Menu extends React.PureComponent { static Switch = SwitchOption static Separator = SeparatorOption static Text = TextOption + static Label = LabelOption public render(): JSX.Element { const {position, children} = this.props From 4543f32435f898e0b3d3f5c7230767d15e0bba44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 15:22:11 +0100 Subject: [PATCH 5/8] Adding value selector/creator widget --- webapp/package-lock.json | 276 +++++++++++++++--- webapp/package.json | 2 + webapp/src/components/cardDetail.scss | 4 + webapp/src/components/cardDetail.tsx | 1 + .../src/components/propertyValueElement.tsx | 48 +-- webapp/src/widgets/valueSelector.scss | 8 + webapp/src/widgets/valueSelector.tsx | 77 +++++ 7 files changed, 352 insertions(+), 64 deletions(-) create mode 100644 webapp/src/widgets/valueSelector.scss create mode 100644 webapp/src/widgets/valueSelector.tsx diff --git a/webapp/package-lock.json b/webapp/package-lock.json index cca380343..404ab4892 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -8,7 +8,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -103,7 +102,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, "requires": { "@babel/types": "^7.10.4" } @@ -172,8 +170,7 @@ "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, "@babel/helpers": { "version": "7.10.4", @@ -190,7 +187,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -201,7 +197,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -210,7 +205,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -221,7 +215,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -229,20 +222,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -404,7 +394,6 @@ "version": "7.11.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", @@ -427,6 +416,94 @@ "minimist": "^1.2.0" } }, + "@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "requires": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + } + }, + "@emotion/core": { + "version": "10.0.35", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.35.tgz", + "integrity": "sha512-sH++vJCdk025fBlRZSAhkRlSUoqSqgCzYf5fMOmqqi3bM6how+sQpg3hkgJonj8GxXM4WbD7dRO+4tegDB9fUw==", + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "requires": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + } + }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + }, + "dependencies": { + "csstype": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz", + "integrity": "sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==" + } + } + }, + "@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==" + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "@eslint/eslintrc": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", @@ -1450,6 +1527,11 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, "@types/prettier": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.2.tgz", @@ -1509,6 +1591,26 @@ "@types/react-router": "*" } }, + "@types/react-select": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-3.0.22.tgz", + "integrity": "sha512-fqgmC979JPr/6476Pau6QnmI9zVV664R7Q92Ld1rgTn+umtUXT5X3+PO/x6O4imCZnh7XCqZcouabWAlAQJNpQ==", + "dev": true, + "requires": { + "@types/react": "*", + "@types/react-dom": "*", + "@types/react-transition-group": "*" + } + }, + "@types/react-transition-group": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", + "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -2275,6 +2377,30 @@ } } }, + "babel-plugin-emotion": { + "version": "10.0.33", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz", + "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -2300,6 +2426,21 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, "babel-preset-current-node-syntax": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", @@ -2657,8 +2798,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camel-case": { "version": "4.1.1", @@ -2980,7 +3120,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" }, @@ -2988,8 +3127,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -3064,6 +3202,18 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", @@ -3467,6 +3617,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -3711,7 +3870,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -3749,8 +3907,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.14.3", @@ -4802,8 +4959,7 @@ "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "find-up": { "version": "4.1.0", @@ -5634,7 +5790,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5643,8 +5798,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" } } }, @@ -5783,8 +5937,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "2.1.0", @@ -7470,8 +7623,7 @@ "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.2.3", @@ -7590,8 +7742,7 @@ "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, "load-json-file": { "version": "2.0.0", @@ -7657,8 +7808,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.memoize": { "version": "4.1.2", @@ -7769,6 +7919,11 @@ "safe-buffer": "^5.1.2" } }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" + }, "memory-fs": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", @@ -8597,7 +8752,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -8619,7 +8773,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -8689,8 +8842,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-to-regexp": { "version": "1.8.0", @@ -8703,8 +8855,7 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "pbkdf2": { "version": "3.1.1", @@ -9097,6 +9248,14 @@ "scheduler": "^0.19.1" } }, + "react-input-autosize": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", + "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==", + "requires": { + "prop-types": "^15.5.8" + } + }, "react-intl": { "version": "5.8.6", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.8.6.tgz", @@ -9159,6 +9318,21 @@ "tiny-warning": "^1.0.0" } }, + "react-select": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz", + "integrity": "sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g==", + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/cache": "^10.0.9", + "@emotion/core": "^10.0.9", + "@emotion/css": "^10.0.9", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^2.2.2", + "react-transition-group": "^4.3.0" + } + }, "react-simplemde-editor": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/react-simplemde-editor/-/react-simplemde-editor-4.1.3.tgz", @@ -9176,6 +9350,17 @@ } } }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -9399,7 +9584,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -10760,8 +10944,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", @@ -12458,6 +12641,11 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 23711b294..6344fd942 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -20,6 +20,7 @@ "react-dom": "^16.13.1", "react-intl": "^5.8.6", "react-router-dom": "^5.2.0", + "react-select": "^3.1.0", "react-simplemde-editor": "^4.1.3" }, "jest": { @@ -40,6 +41,7 @@ "@types/react-dom": "^16.9.8", "@types/react-intl": "^3.0.0", "@types/react-router-dom": "^5.1.6", + "@types/react-select": "^3.0.22", "@typescript-eslint/eslint-plugin": "^4.4.1", "@typescript-eslint/parser": "^4.4.1", "copy-webpack-plugin": "^6.0.3", diff --git a/webapp/src/components/cardDetail.scss b/webapp/src/components/cardDetail.scss index b213eac32..a2f8adbd3 100644 --- a/webapp/src/components/cardDetail.scss +++ b/webapp/src/components/cardDetail.scss @@ -32,6 +32,10 @@ display: flex; flex-direction: row; margin: 8px 0; + .MenuWrapper { + display: flex; + align-items: center; + } } .octo-propertyname { diff --git a/webapp/src/components/cardDetail.tsx b/webapp/src/components/cardDetail.tsx index 7b32dd7e8..1c04f9a66 100644 --- a/webapp/src/components/cardDetail.tsx +++ b/webapp/src/components/cardDetail.tsx @@ -193,6 +193,7 @@ class CardDetail extends React.Component { diff --git a/webapp/src/components/propertyValueElement.tsx b/webapp/src/components/propertyValueElement.tsx index f8e02f486..0d5f457b7 100644 --- a/webapp/src/components/propertyValueElement.tsx +++ b/webapp/src/components/propertyValueElement.tsx @@ -7,12 +7,17 @@ import {Card} from '../blocks/card' import {IPropertyTemplate, IPropertyOption} from '../blocks/board' import {OctoUtils} from '../octoUtils' import mutator from '../mutator' +import {Utils} from '../utils' +import {BoardTree} from '../viewModel/boardTree' import Editable from '../widgets/editable' import MenuWrapper from '../widgets/menuWrapper' import Menu from '../widgets/menu' +import ValueSelector from '../widgets/valueSelector' +import {skipPartiallyEmittedExpressions} from 'typescript' type Props = { + boardTree?: BoardTree readOnly: boolean card: Card propertyTemplate: IPropertyTemplate @@ -54,32 +59,35 @@ export default class PropertyValueElement extends React.Component className += ' empty' } - return ( - + if (readOnly) { + return (
{finalDisplayValue}
- {readOnly ? null : ( - - mutator.changePropertyValue(card, propertyTemplate.id, '')} - /> - {propertyTemplate.options.map((o: IPropertyOption): JSX.Element => ( - mutator.changePropertyValue(card, propertyTemplate.id, o.id)} - /> - ))} - - )} -
+ ) + } + return ( + p.id === propertyValue)} + onChange={(value) => { + mutator.changePropertyValue(card, propertyTemplate.id, value) + }} + onCreate={ + async (value) => { + const option: IPropertyOption = { + id: Utils.createGuid(), + value, + color: 'propColorDefault', + } + await mutator.insertPropertyOption(this.props.boardTree, propertyTemplate, option, 'add property option') + mutator.changePropertyValue(card, propertyTemplate.id, option.id) + } + } + /> ) } diff --git a/webapp/src/widgets/valueSelector.scss b/webapp/src/widgets/valueSelector.scss new file mode 100644 index 000000000..cca77e349 --- /dev/null +++ b/webapp/src/widgets/valueSelector.scss @@ -0,0 +1,8 @@ +.ValueSelector { + width: 100%; + border-radius: 5px; + color: rgb(var(--main-fg)); + &:hover { + background-color: rgba(var(--main-fg), 0.1), + } +} diff --git a/webapp/src/widgets/valueSelector.tsx b/webapp/src/widgets/valueSelector.tsx new file mode 100644 index 000000000..0327f0696 --- /dev/null +++ b/webapp/src/widgets/valueSelector.tsx @@ -0,0 +1,77 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React, {CSSProperties} from 'react' +import {ActionMeta, ValueType} from 'react-select' +import CreatableSelect from 'react-select/creatable'; +import boardCard from 'src/components/boardCard'; +import {IPropertyOption} from '../blocks/board' + +import './valueSelector.scss' + +type Props = { + options: IPropertyOption[] + value: IPropertyOption; + onCreate?: (value: string) => void + onChange?: (value: string) => void +} + +export default class ValueSelector extends React.Component { + public shouldComponentUpdate(): boolean { + return true + } + + public render(): JSX.Element { + return ( + ({ + ...provided, + display: 'none', + }), + menu: (provided: CSSProperties): CSSProperties => ({ + ...provided, + background: 'rgb(var(--main-bg))', + }), + option: (provided: CSSProperties, state: {isFocused: boolean}): CSSProperties => ({ + ...provided, + background: state.isFocused ? 'rgb(var(--button-bg))' : 'rgb(var(--main-bg))', + color: state.isFocused ? 'rgb(var(--button-fg))' : 'rgb(var(--main-fg))', + padding: '2px 8px', + }), + control: (): CSSProperties => ({ + border: 0, + }), + valueContainer: (provided: CSSProperties): CSSProperties => ({ + ...provided, + padding: '0 8px', + }), + singleValue: (provided: CSSProperties): CSSProperties => ({ + ...provided, + color: 'rgb(var(--main-fg))', + }), + input: (provided: CSSProperties): CSSProperties => ({ + ...provided, + paddingBottom: 0, + paddingTop: 0, + marginBottom: 0, + marginTop: 0, + }), + }} + className='ValueSelector' + hideSelectedOptions={true} + options={this.props.options} + getOptionLabel={(o: IPropertyOption) => o.value} + getOptionValue={(o: IPropertyOption) => o.id} + onChange={(value: ValueType, action: ActionMeta): void => { + if (action.action === 'select-option') { + this.props.onChange((value as IPropertyOption).id) + } + }} + onCreateOption={this.props.onCreate} + autoFocus={true} + value={this.props.value} + closeMenuOnSelect={true} + /> + ) + } +} From e3e5d1d610963162b18b2db5aa9898d419534959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 16:49:19 +0100 Subject: [PATCH 6/8] Adding delete/duplicate icons to the boardCard menu --- webapp/src/components/boardCard.tsx | 4 ++++ webapp/src/widgets/icons/delete.scss | 6 ++++++ webapp/src/widgets/icons/delete.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/icons/duplicate.scss | 6 ++++++ webapp/src/widgets/icons/duplicate.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/menu/menu.scss | 5 +++++ webapp/src/widgets/menu/textOption.tsx | 2 +- 7 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 webapp/src/widgets/icons/delete.scss create mode 100644 webapp/src/widgets/icons/delete.tsx create mode 100644 webapp/src/widgets/icons/duplicate.scss create mode 100644 webapp/src/widgets/icons/duplicate.tsx diff --git a/webapp/src/components/boardCard.tsx b/webapp/src/components/boardCard.tsx index 9664ae0b5..ad780846a 100644 --- a/webapp/src/components/boardCard.tsx +++ b/webapp/src/components/boardCard.tsx @@ -11,6 +11,8 @@ import mutator from '../mutator' import MenuWrapper from '../widgets/menuWrapper' import Menu from '../widgets/menu' import OptionsIcon from '../widgets/icons/options' +import DeleteIcon from '../widgets/icons/delete' +import DuplicateIcon from '../widgets/icons/duplicate' import PropertyValueElement from './propertyValueElement' @@ -89,11 +91,13 @@ class BoardCard extends React.Component {
} id='delete' name={intl.formatMessage({id: 'BoardCard.delete', defaultMessage: 'Delete'})} onClick={() => mutator.deleteBlock(card, 'delete card')} /> } id='duplicate' name={intl.formatMessage({id: 'BoardCard.duplicate', defaultMessage: 'Duplicate'})} onClick={() => mutator.insertBlock(MutableBlock.duplicate(card), 'duplicate card')} diff --git a/webapp/src/widgets/icons/delete.scss b/webapp/src/widgets/icons/delete.scss new file mode 100644 index 000000000..f3971ef38 --- /dev/null +++ b/webapp/src/widgets/icons/delete.scss @@ -0,0 +1,6 @@ +.DeleteIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/delete.tsx b/webapp/src/widgets/icons/delete.tsx new file mode 100644 index 000000000..8c4f098a3 --- /dev/null +++ b/webapp/src/widgets/icons/delete.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './delete.scss' + +export default function DeleteIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/icons/duplicate.scss b/webapp/src/widgets/icons/duplicate.scss new file mode 100644 index 000000000..a6ac80689 --- /dev/null +++ b/webapp/src/widgets/icons/duplicate.scss @@ -0,0 +1,6 @@ +.DuplicateIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/duplicate.tsx b/webapp/src/widgets/icons/duplicate.tsx new file mode 100644 index 000000000..39c683ab7 --- /dev/null +++ b/webapp/src/widgets/icons/duplicate.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './duplicate.scss' + +export default function DuplicateIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/menu/menu.scss b/webapp/src/widgets/menu/menu.scss index cc6cc45f9..303deaad5 100644 --- a/webapp/src/widgets/menu/menu.scss +++ b/webapp/src/widgets/menu/menu.scss @@ -47,5 +47,10 @@ .SubmenuTriangleIcon { fill: rgba(var(--main-fg), 0.7); } + .Icon { + width: 16px; + height: 16px; + margin-right: 3px; + } } } diff --git a/webapp/src/widgets/menu/textOption.tsx b/webapp/src/widgets/menu/textOption.tsx index 80784b32f..227c990b6 100644 --- a/webapp/src/widgets/menu/textOption.tsx +++ b/webapp/src/widgets/menu/textOption.tsx @@ -20,8 +20,8 @@ export default class TextOption extends React.PureComponent { className='MenuOption TextOption menu-option' onClick={this.handleOnClick} > -
{name}
{icon} +
{name}
) } From 1479eeccfa2f213e3ff55a514f34f9cc44aa0e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 18:31:40 +0100 Subject: [PATCH 7/8] Adding a bunch of icons --- webapp/src/components/boardComponent.tsx | 7 +++++++ webapp/src/components/cardDialog.tsx | 2 ++ webapp/src/components/comment.tsx | 4 +++- webapp/src/components/contentBlock.scss | 10 ++++++++++ webapp/src/components/contentBlock.tsx | 20 +++++++++++++++++--- webapp/src/widgets/icons/hide.scss | 6 ++++++ webapp/src/widgets/icons/hide.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/icons/image.scss | 6 ++++++ webapp/src/widgets/icons/image.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/icons/show.scss | 6 ++++++ webapp/src/widgets/icons/show.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/icons/text.scss | 6 ++++++ webapp/src/widgets/icons/text.tsx | 20 ++++++++++++++++++++ webapp/src/widgets/menu/menu.scss | 2 +- webapp/src/widgets/menu/subMenuOption.tsx | 2 ++ 15 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 webapp/src/components/contentBlock.scss create mode 100644 webapp/src/widgets/icons/hide.scss create mode 100644 webapp/src/widgets/icons/hide.tsx create mode 100644 webapp/src/widgets/icons/image.scss create mode 100644 webapp/src/widgets/icons/image.tsx create mode 100644 webapp/src/widgets/icons/show.scss create mode 100644 webapp/src/widgets/icons/show.tsx create mode 100644 webapp/src/widgets/icons/text.scss create mode 100644 webapp/src/widgets/icons/text.tsx diff --git a/webapp/src/components/boardComponent.tsx b/webapp/src/components/boardComponent.tsx index 484620a62..fb029b317 100644 --- a/webapp/src/components/boardComponent.tsx +++ b/webapp/src/components/boardComponent.tsx @@ -16,6 +16,9 @@ import Menu from '../widgets/menu' import MenuWrapper from '../widgets/menuWrapper' import OptionsIcon from '../widgets/icons/options' import AddIcon from '../widgets/icons/add' +import HideIcon from '../widgets/icons/hide' +import ShowIcon from '../widgets/icons/show' +import DeleteIcon from '../widgets/icons/delete' import Button from '../widgets/buttons/button' import BoardCard from './boardCard' @@ -309,6 +312,7 @@ class BoardComponent extends React.Component { } name={intl.formatMessage({id: 'BoardComponent.hide', defaultMessage: 'Hide'})} onClick={() => mutator.hideViewColumn(activeView, '')} /> @@ -372,11 +376,13 @@ class BoardComponent extends React.Component { } name={intl.formatMessage({id: 'BoardComponent.hide', defaultMessage: 'Hide'})} onClick={() => mutator.hideViewColumn(activeView, group.option.id)} /> } name={intl.formatMessage({id: 'BoardComponent.delete', defaultMessage: 'Delete'})} onClick={() => mutator.deletePropertyOption(boardTree, boardTree.groupByProperty, group.option)} /> @@ -450,6 +456,7 @@ class BoardComponent extends React.Component { } name={intl.formatMessage({id: 'BoardComponent.show', defaultMessage: 'Show'})} onClick={() => mutator.unhideViewColumn(activeView, group.option.id)} /> diff --git a/webapp/src/components/cardDialog.tsx b/webapp/src/components/cardDialog.tsx index 3d8de40ed..8a5bec0c0 100644 --- a/webapp/src/components/cardDialog.tsx +++ b/webapp/src/components/cardDialog.tsx @@ -6,6 +6,7 @@ import {Card} from '../blocks/card' import {BoardTree} from '../viewModel/boardTree' import mutator from '../mutator' import Menu from '../widgets/menu' +import DeleteIcon from '../widgets/icons/delete' import CardDetail from './cardDetail' import Dialog from './dialog' @@ -22,6 +23,7 @@ class CardDialog extends React.Component { } name='Delete' onClick={async () => { await mutator.deleteBlock(this.props.card, 'delete card') diff --git a/webapp/src/components/comment.tsx b/webapp/src/components/comment.tsx index 84e85df7d..8408532ef 100644 --- a/webapp/src/components/comment.tsx +++ b/webapp/src/components/comment.tsx @@ -8,6 +8,7 @@ import {IBlock} from '../blocks/block' import Menu from '../widgets/menu' import MenuWrapper from '../widgets/menuWrapper' +import DeleteIcon from '../widgets/icons/delete' import './comment.scss' import {Utils} from '../utils' @@ -36,8 +37,9 @@ const Comment: FC = (props: Props) => {
{(new Date(comment.createAt)).toLocaleTimeString()}
{'...'}
- + } id='delete' name={intl.formatMessage({id: 'Comment.delete', defaultMessage: 'Delete'})} onClick={() => mutator.deleteBlock(comment)} diff --git a/webapp/src/components/contentBlock.scss b/webapp/src/components/contentBlock.scss new file mode 100644 index 000000000..9557773f9 --- /dev/null +++ b/webapp/src/components/contentBlock.scss @@ -0,0 +1,10 @@ +.ContentBlock { + .MenuWrapper { + display: none; + } + &:hover { + .MenuWrapper { + display: flex; + } + } +} diff --git a/webapp/src/components/contentBlock.tsx b/webapp/src/components/contentBlock.tsx index ffa2e74e0..f5936d719 100644 --- a/webapp/src/components/contentBlock.tsx +++ b/webapp/src/components/contentBlock.tsx @@ -13,9 +13,17 @@ import {MutableTextBlock} from '../blocks/textBlock' import Menu from '../widgets/menu' import MenuWrapper from '../widgets/menuWrapper' import OptionsIcon from '../widgets/icons/options' +import SortUpIcon from '../widgets/icons/sortUp' +import SortDownIcon from '../widgets/icons/sortDown' +import DeleteIcon from '../widgets/icons/delete' +import AddIcon from '../widgets/icons/add' +import TextIcon from '../widgets/icons/text' +import ImageIcon from '../widgets/icons/image' import {MarkdownEditor} from './markdownEditor' +import './contentBlock.scss' + type Props = { block: IOrderedBlock cardId: string @@ -23,7 +31,7 @@ type Props = { } class ContentBlock extends React.Component { - shouldComponentUpdate() { + shouldComponentUpdate(): boolean { return true } @@ -34,15 +42,16 @@ class ContentBlock extends React.Component { } const index = cardTree.contents.indexOf(block) return ( -
+
-
+
{index > 0 && } onClick={() => { const previousBlock = cardTree.contents[index - 1] const newOrder = OctoUtils.getOrderBefore(previousBlock, cardTree.contents) @@ -54,6 +63,7 @@ class ContentBlock extends React.Component { } onClick={() => { const nextBlock = cardTree.contents[index + 1] const newOrder = OctoUtils.getOrderAfter(nextBlock, cardTree.contents) @@ -64,10 +74,12 @@ class ContentBlock extends React.Component { } > } onClick={() => { const newBlock = new MutableTextBlock() newBlock.parentId = cardId @@ -81,6 +93,7 @@ class ContentBlock extends React.Component { } onClick={() => { Utils.selectLocalFile( (file) => { @@ -91,6 +104,7 @@ class ContentBlock extends React.Component { /> } id='delete' name='Delete' onClick={() => mutator.deleteBlock(block)} diff --git a/webapp/src/widgets/icons/hide.scss b/webapp/src/widgets/icons/hide.scss new file mode 100644 index 000000000..ef7b09e30 --- /dev/null +++ b/webapp/src/widgets/icons/hide.scss @@ -0,0 +1,6 @@ +.HideIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/hide.tsx b/webapp/src/widgets/icons/hide.tsx new file mode 100644 index 000000000..41801df8f --- /dev/null +++ b/webapp/src/widgets/icons/hide.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './hide.scss' + +export default function HideIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/icons/image.scss b/webapp/src/widgets/icons/image.scss new file mode 100644 index 000000000..b3ef5b0f8 --- /dev/null +++ b/webapp/src/widgets/icons/image.scss @@ -0,0 +1,6 @@ +.ImageIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/image.tsx b/webapp/src/widgets/icons/image.tsx new file mode 100644 index 000000000..fcd4ef843 --- /dev/null +++ b/webapp/src/widgets/icons/image.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './image.scss' + +export default function ImageIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/icons/show.scss b/webapp/src/widgets/icons/show.scss new file mode 100644 index 000000000..885a157b0 --- /dev/null +++ b/webapp/src/widgets/icons/show.scss @@ -0,0 +1,6 @@ +.ShowIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/show.tsx b/webapp/src/widgets/icons/show.tsx new file mode 100644 index 000000000..02a7eb960 --- /dev/null +++ b/webapp/src/widgets/icons/show.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './show.scss' + +export default function ShowIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/icons/text.scss b/webapp/src/widgets/icons/text.scss new file mode 100644 index 000000000..f8118c38d --- /dev/null +++ b/webapp/src/widgets/icons/text.scss @@ -0,0 +1,6 @@ +.TextIcon { + fill: rgba(var(--main-fg), 0.7); + stroke: none; + width: 24px; + height: 24px; +} diff --git a/webapp/src/widgets/icons/text.tsx b/webapp/src/widgets/icons/text.tsx new file mode 100644 index 000000000..5e425da79 --- /dev/null +++ b/webapp/src/widgets/icons/text.tsx @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' + +import './text.scss' + +export default function TextIcon(): JSX.Element { + return ( + + + + ) +} diff --git a/webapp/src/widgets/menu/menu.scss b/webapp/src/widgets/menu/menu.scss index 303deaad5..2181b768c 100644 --- a/webapp/src/widgets/menu/menu.scss +++ b/webapp/src/widgets/menu/menu.scss @@ -50,7 +50,7 @@ .Icon { width: 16px; height: 16px; - margin-right: 3px; + margin-right: 5px; } } } diff --git a/webapp/src/widgets/menu/subMenuOption.tsx b/webapp/src/widgets/menu/subMenuOption.tsx index e1b6f912f..84aff128a 100644 --- a/webapp/src/widgets/menu/subMenuOption.tsx +++ b/webapp/src/widgets/menu/subMenuOption.tsx @@ -10,6 +10,7 @@ import './subMenuOption.scss' type SubMenuOptionProps = MenuOptionProps & { position?: 'bottom' | 'top' + icon?: React.ReactNode } type SubMenuState = { @@ -36,6 +37,7 @@ export default class SubMenuOption extends React.PureComponent + {this.props.icon}
{this.props.name}
{this.state.isOpen && From f4a0c28bdaf0d892e703faea5a390f5086f96fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 30 Oct 2020 18:40:46 +0100 Subject: [PATCH 8/8] Fixing table select elements --- webapp/src/components/tableComponent.scss | 1 - webapp/src/components/tableRow.tsx | 1 + webapp/src/widgets/editable.scss | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/tableComponent.scss b/webapp/src/components/tableComponent.scss index 24946438c..c37e4621b 100644 --- a/webapp/src/components/tableComponent.scss +++ b/webapp/src/components/tableComponent.scss @@ -15,7 +15,6 @@ font-size: 14px; line-height: 21px; - overflow: hidden; position: relative; .octo-icontitle { diff --git a/webapp/src/components/tableRow.tsx b/webapp/src/components/tableRow.tsx index 8e3c1c855..b2e36ba6e 100644 --- a/webapp/src/components/tableRow.tsx +++ b/webapp/src/components/tableRow.tsx @@ -114,6 +114,7 @@ class TableRow extends React.Component { diff --git a/webapp/src/widgets/editable.scss b/webapp/src/widgets/editable.scss index b13717e85..2680ece3c 100644 --- a/webapp/src/widgets/editable.scss +++ b/webapp/src/widgets/editable.scss @@ -1,6 +1,8 @@ .Editable { cursor: text; border: 0; + overflow: hidden; + text-overflow: ellipsis; &.active { min-width: 100px; }