feat: remeber file list view

This commit is contained in:
zerosoul
2022-03-31 17:46:07 +08:00
parent 8f2c14436f
commit 6be6dc6458
10 changed files with 205 additions and 34 deletions
+92
View File
@@ -0,0 +1,92 @@
// import React from 'react'
// import { useSelector } from "react-redux";
import styled from "styled-components";
import CheckSign from "../../../assets/icons/check.sign.svg";
const Styled = styled.div`
padding: 12px;
background: #ffffff;
min-width: 200px;
/* max-height: 230px; */
overflow: auto;
box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18);
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
> .list {
width: 100%;
display: flex;
flex-direction: column;
gap: 16px;
.type {
position: relative;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
color: #616161;
.icon {
width: 15px;
height: auto;
}
.check {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
}
}
`;
export const Dates = {
today: {
title: "Today",
duration: 2222,
},
in7d: {
title: "Last 7 Days",
},
in30d: {
title: "Last 30 Days",
},
in3m: {
title: "Last 3 months",
},
in12m: {
title: "Last 12 months",
},
};
export default function Date({ select = "", updateFilter }) {
// const { input, updateInput, contacts } = useFilteredUsers();
// const contacts=useSelector(store=>store.contacts);
// const uid=contacts.ids;
// const dataMap=contacts.byId;
const handleClick = (dur) => {
updateFilter({ date: dur });
};
return (
<Styled>
<ul className="list">
<li className="type" onClick={handleClick.bind(null, undefined)}>
Any Time
{!select && <CheckSign className="check" />}
</li>
{Object.entries(Dates).map(([_key, { title }]) => {
return (
<li
key={title}
className="type"
onClick={handleClick.bind(null, _key)}
>
{title}
{select == _key && <CheckSign className="check" />}
</li>
);
})}
</ul>
</Styled>
);
}
+2 -2
View File
@@ -1,5 +1,5 @@
// import React from 'react'
import { useSelector } from "react-redux";
// import { useSelector } from "react-redux";
import styled from "styled-components";
import Search from "../Search";
import CheckSign from "../../../assets/icons/check.sign.svg";
@@ -9,7 +9,7 @@ import useFilteredUsers from "../../../common/hook/useFilteredUsers";
const Styled = styled.div`
padding: 0 4px 4px 4px;
background: #ffffff;
max-height: 230px;
max-height: 300px;
overflow: auto;
box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18);
border-radius: 8px;
+3 -3
View File
@@ -1,5 +1,5 @@
// import React from 'react'
import { useSelector } from "react-redux";
// import { useSelector } from "react-redux";
import styled from "styled-components";
import IconPdf from "../../../assets/icons/file.pdf.svg";
import IconAudio from "../../../assets/icons/file.audio.svg";
@@ -83,8 +83,8 @@ export default function Type({ select = "", updateFilter }) {
// const uid=contacts.ids;
// const dataMap=contacts.byId;
const handleClick = (uid) => {
updateFilter({ type: uid });
const handleClick = (type) => {
updateFilter({ type });
};
return (
<Styled>
+72 -10
View File
@@ -1,12 +1,12 @@
// import React from "react";
import { useState } from "react";
import styled from "styled-components";
import Tippy from "@tippyjs/react";
import { useSelector } from "react-redux";
import { FileTypes } from "./Type";
import Avatar from "../../../common/component/Avatar";
import FilterDate, { Dates } from "./Date";
import FilterFrom from "./From";
import FilterChannel from "./Channel";
import FilterType from "./Type";
import FilterType, { FileTypes } from "./Type";
import ArrowDown from "../../../assets/icons/arrow.down.svg";
const Styled = styled.div`
/* padding: 20px 0; */
@@ -43,22 +43,53 @@ const Styled = styled.div`
`;
export default function Filter({ filter, updateFilter }) {
const [filtersVisible, setFiltersVisible] = useState({
channel: false,
date: false,
from: false,
type: false,
});
const toggleFilterVisible = (obj) => {
setFiltersVisible((prev) => {
return { ...prev, ...obj };
});
};
const handleUpdateFilter = (data) => {
updateFilter(data);
let _key = Object.keys(data)[0];
let tmp = {
[_key]: false,
};
console.log("wtffff", tmp);
toggleFilterVisible(tmp);
};
const { contactMap, channelMap } = useSelector((store) => {
return { contactMap: store.contacts.byId, channelMap: store.channels.byId };
});
console.log("maps", contactMap, filter);
const { from, channel, type } = filter;
const { from, channel, type, date } = filter;
const {
channel: channelVisible,
date: dateVisible,
type: typeVisible,
from: fromVisible,
} = filtersVisible;
return (
<Styled>
<Tippy
interactive
onClickOutside={toggleFilterVisible.bind(null, { from: false })}
visible={fromVisible}
placement="bottom-start"
trigger="click"
content={
<FilterFrom select={filter.from} updateFilter={updateFilter} />
<FilterFrom select={filter.from} updateFilter={handleUpdateFilter} />
}
>
<div className={`filter ${from && "selected"}`}>
<div
className={`filter ${from && "selected"}`}
onClick={toggleFilterVisible.bind(null, { from: true })}
>
{from && (
<Avatar
className="avatar"
@@ -72,13 +103,21 @@ export default function Filter({ filter, updateFilter }) {
</Tippy>
<Tippy
interactive
onClickOutside={toggleFilterVisible.bind(null, { channel: false })}
visible={channelVisible}
placement="bottom-start"
trigger="click"
content={
<FilterChannel select={filter.channel} updateFilter={updateFilter} />
<FilterChannel
select={filter.channel}
updateFilter={handleUpdateFilter}
/>
}
>
<div className={`filter ${channel && "selected"}`}>
<div
className={`filter ${channel && "selected"}`}
onClick={toggleFilterVisible.bind(null, { channel: true })}
>
<span className="txt">
{channel ? `In ${channelMap[channel].name}` : `Channel`}
</span>
@@ -87,17 +126,40 @@ export default function Filter({ filter, updateFilter }) {
</Tippy>
<Tippy
interactive
onClickOutside={toggleFilterVisible.bind(null, { type: false })}
visible={typeVisible}
placement="bottom-start"
trigger="click"
content={
<FilterType select={filter.type} updateFilter={updateFilter} />
<FilterType select={filter.type} updateFilter={handleUpdateFilter} />
}
>
<div className={`filter ${type && "selected"}`}>
<div
className={`filter ${type && "selected"}`}
onClick={toggleFilterVisible.bind(null, { type: true })}
>
<span className="txt">{type ? FileTypes[type].title : "Type"}</span>
<ArrowDown className="arrow" />
</div>
</Tippy>
<Tippy
interactive
onClickOutside={toggleFilterVisible.bind(null, { date: false })}
visible={dateVisible}
placement="bottom-start"
trigger="click"
content={
<FilterDate select={filter.date} updateFilter={handleUpdateFilter} />
}
>
<div
className={`filter ${date && "selected"}`}
onClick={toggleFilterVisible.bind(null, { date: true })}
>
<span className="txt">{date ? Dates[date].title : "Date"}</span>
<ArrowDown className="arrow" />
</div>
</Tippy>
</Styled>
);
}
+4 -2
View File
@@ -29,13 +29,15 @@ export default function Search({
embed = false,
}) {
const handleChange = (evt) => {
updateSearchValue(evt.target.value);
if (updateSearchValue) {
updateSearchValue(evt.target.value);
}
};
return (
<Styled className={embed ? "embed" : ""}>
<input
value={value}
onChange={updateSearchValue ? handleChange : null}
onChange={handleChange}
className="search"
placeholder="Search..."
/>
+7 -6
View File
@@ -1,5 +1,8 @@
// import React from 'react'
import styled from "styled-components";
import { useDispatch } from "react-redux";
import { updateFileListView } from "../../app/slices/ui";
import { Views } from "../../app/config";
import IconList from "../../assets/icons/file.list.svg";
import IconGrid from "../../assets/icons/file.grid.svg";
const Styled = styled.ul`
@@ -27,15 +30,13 @@ const Styled = styled.ul`
}
}
`;
export const Views = {
item: "item",
grid: "grid",
};
export default function View({ view = Views.item, toggleView }) {
export default function View({ view = Views.item }) {
const dispatch = useDispatch();
const handleChangeView = (evt) => {
const { view: clickView } = evt.currentTarget.dataset;
if (clickView == view) return;
toggleView();
dispatch(updateFileListView(view == Views.item ? Views.grid : Views.item));
};
return (
<Styled className={view}>
+9 -8
View File
@@ -3,7 +3,8 @@ import Styled from "./styled";
import { useSelector } from "react-redux";
import Masonry from "masonry-layout";
// import waterfall from "waterfall.js/src/waterfall";
import View, { Views } from "./View";
import { Views } from "../../app/config";
import View from "./View";
import Search from "./Search";
import Filter from "./Filter";
import FileBox from "../../common/component/FileBox";
@@ -11,14 +12,14 @@ let msnry = null;
export default function ResourceManagement() {
const listContainerRef = useRef(null);
const [filter, setFilter] = useState({});
const [view, setView] = useState(Views.item);
const { fileMessages, message } = useSelector((store) => {
return { message: store.message, fileMessages: store.fileMessage };
const { fileMessages, message, view } = useSelector((store) => {
return {
message: store.message,
fileMessages: store.fileMessage,
view: store.ui.fileListView,
};
});
const toggleView = () => {
setView((prev) => (prev == Views.item ? Views.grid : Views.item));
};
const updateFilter = (data) => {
setFilter((prev) => {
return { ...prev, ...data };
@@ -50,7 +51,7 @@ export default function ResourceManagement() {
<div className="divider"></div>
<div className="opts">
<Filter filter={filter} updateFilter={updateFilter} />
<View view={view} toggleView={toggleView} />
<View view={view} />
</div>
<div className={`list ${view}`} ref={listContainerRef}>
{fileMessages.map((id) => {