Add support for sharing table views via link
This commit is contained in:
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Zobrazit archivované",
|
||||
"notAccessTitle": "Nemáte oprávnění k přístupu",
|
||||
"hideColumns": "Skrýt sloupce",
|
||||
"clearFilters": "Zrušit filtry"
|
||||
"clearFilters": "Zrušit filtry",
|
||||
"share": "sdílet"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Jste si jisti, že chcete odejít? Máte neuložené změny.",
|
||||
"notifications": {
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
"clone": "Duplizieren",
|
||||
"notAccessTitle": "Keine Berechtigung, um hierauf zuzugreifen",
|
||||
"hideColumns": "Spalten anpassen",
|
||||
"clearFilters": "Filter leeren"
|
||||
"clearFilters": "Filter leeren",
|
||||
"share": "Teilen"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Sicher? Nicht gespeicherte Änderungen gehen verloren!",
|
||||
"notifications": {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Show Archived",
|
||||
"notAccessTitle": "You don't have permission to access",
|
||||
"hideColumns": "Hide Columns",
|
||||
"clearFilters": "Clear Filters"
|
||||
"clearFilters": "Clear Filters",
|
||||
"share": "Share"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Are you sure you want to leave? You have unsaved changes.",
|
||||
"notifications": {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Mostrar Archivados",
|
||||
"notAccessTitle": "No tienes permiso de acceso",
|
||||
"hideColumns": "Ocultar Columnas",
|
||||
"clearFilters": "Borrar filtros"
|
||||
"clearFilters": "Borrar filtros",
|
||||
"share": "compartir"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Seguro que quieres salir?. Hay cambios sin guardar.",
|
||||
"notifications": {
|
||||
|
||||
@@ -153,7 +153,8 @@
|
||||
"clearFilters": "Effacer les filtres",
|
||||
"unArchive": "Désarchiver",
|
||||
"clone": "Cloner",
|
||||
"clear": "Effacer"
|
||||
"clear": "Effacer",
|
||||
"share": "partager"
|
||||
},
|
||||
"filament": {
|
||||
"fields_help": {
|
||||
|
||||
@@ -152,7 +152,8 @@
|
||||
"clearFilters": "Szűrők törlése",
|
||||
"unArchive": "Arhiválás visszavonása",
|
||||
"clone": "Másolás",
|
||||
"clear": "Törlés"
|
||||
"clear": "Törlés",
|
||||
"share": "Ossza meg"
|
||||
},
|
||||
"filament": {
|
||||
"fields_help": {
|
||||
|
||||
@@ -152,7 +152,8 @@
|
||||
"clearFilters": "Cancella Filtri",
|
||||
"unArchive": "Ripristina",
|
||||
"clone": "Clona",
|
||||
"clear": "Pulisci"
|
||||
"clear": "Pulisci",
|
||||
"share": "condividere"
|
||||
},
|
||||
"filament": {
|
||||
"fields_help": {
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"clear": "Tøm",
|
||||
"filter": "Filtrer",
|
||||
"refresh": "Gjenoppfrisk",
|
||||
"notAccessTitle": "Du har ikke rettighet til å få tilgang"
|
||||
"notAccessTitle": "Du har ikke rettighet til å få tilgang",
|
||||
"share": "Andel"
|
||||
},
|
||||
"filament": {
|
||||
"fields": {
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"clearFilters": "Filters leegmaken",
|
||||
"unArchive": "Dearchiveren",
|
||||
"clone": "Klonen",
|
||||
"clear": "Wissen"
|
||||
"clear": "Wissen",
|
||||
"share": "delen"
|
||||
},
|
||||
"actions": {
|
||||
"create": "Aanmaken",
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Pokaż zarchiwizowane",
|
||||
"notAccessTitle": "Nie masz zezwolenia na dostęp",
|
||||
"hideColumns": "Edytuj kolumny",
|
||||
"clearFilters": "Wyczyść filtry"
|
||||
"clearFilters": "Wyczyść filtry",
|
||||
"share": "udział"
|
||||
},
|
||||
"spool": {
|
||||
"titles": {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Показать архивные",
|
||||
"notAccessTitle": "У вас нет разрешения на доступ",
|
||||
"hideColumns": "Скрыть столбцы",
|
||||
"clearFilters": "Очистить фильтр"
|
||||
"clearFilters": "Очистить фильтр",
|
||||
"share": "делиться"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Вы уверены, что хотите выйти? У вас есть несохраненные изменения.",
|
||||
"notifications": {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "Visa arkiverade",
|
||||
"notAccessTitle": "Du har inte tillgång till denna sida",
|
||||
"hideColumns": "Dölj kolumner",
|
||||
"clearFilters": "Rensa filter"
|
||||
"clearFilters": "Rensa filter",
|
||||
"share": "aktie"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "Är du säker på att du vill lämna sidan? Du har osparade ändringar.",
|
||||
"notifications": {
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"logout": "Вийти",
|
||||
"notAccessTitle": "У Вас бракує прав для доступу",
|
||||
"clone": "Клонувати",
|
||||
"unArchive": "Розархівувати"
|
||||
"unArchive": "Розархівувати",
|
||||
"share": "частка"
|
||||
},
|
||||
"spool": {
|
||||
"fields": {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"showArchived": "显示存档",
|
||||
"notAccessTitle": "您没有访问权限",
|
||||
"hideColumns": "隐藏列",
|
||||
"clearFilters": "清除筛选器"
|
||||
"clearFilters": "清除筛选器",
|
||||
"share": "分享"
|
||||
},
|
||||
"warnWhenUnsavedChanges": "您确定要离开吗?您有未保存的更改。",
|
||||
"notifications": {
|
||||
|
||||
@@ -5,8 +5,8 @@ import { Table, Space, Button, Dropdown } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import { IFilament } from "./model";
|
||||
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
||||
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined, ShareAltOutlined } from "@ant-design/icons";
|
||||
import { TableState, shareSavedState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||
import {
|
||||
DateColumn,
|
||||
FilteredQueryColumn,
|
||||
@@ -164,6 +164,20 @@ export const FilamentList: React.FC<IResourceComponentsProps> = () => {
|
||||
{t("buttons.hideColumns")}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Button type="primary" icon={<ShareAltOutlined />} onClick={() => {
|
||||
let url = shareSavedState("filamentList-v2");
|
||||
try {
|
||||
if (navigator.canShare()) {
|
||||
navigator.share({ url: url });
|
||||
} else {
|
||||
window.location.hash = url.split("#")[1]
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}}>
|
||||
{t("buttons.share")}
|
||||
</Button>
|
||||
{defaultButtons}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -5,8 +5,8 @@ import { Table, Space, Button, Dropdown, Modal } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import { ISpool } from "./model";
|
||||
import { TableState, useInitialTableState, useSavedState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined, InboxOutlined, ToTopOutlined } from "@ant-design/icons";
|
||||
import { TableState, shareSavedState, useInitialTableState, useSavedState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined, InboxOutlined, ShareAltOutlined, ToTopOutlined } from "@ant-design/icons";
|
||||
import {
|
||||
DateColumn,
|
||||
FilteredQueryColumn,
|
||||
@@ -221,6 +221,20 @@ export const SpoolList: React.FC<IResourceComponentsProps> = () => {
|
||||
{t("buttons.hideColumns")}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Button type="primary" icon={<ShareAltOutlined />} onClick={() => {
|
||||
let url = shareSavedState("spoolList-v2");
|
||||
try {
|
||||
if (navigator.canShare()) {
|
||||
navigator.share({ url: url });
|
||||
} else {
|
||||
window.location.hash = url.split("#")[1]
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}}>
|
||||
{t("buttons.share")}
|
||||
</Button>
|
||||
{defaultButtons}
|
||||
</>
|
||||
)}
|
||||
|
||||
18
client/src/pages/vendors/list.tsx
vendored
18
client/src/pages/vendors/list.tsx
vendored
@@ -5,8 +5,8 @@ import { Table, Space, Button, Dropdown } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import { IVendor } from "./model";
|
||||
import { TableState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined } from "@ant-design/icons";
|
||||
import { TableState, shareSavedState, useInitialTableState, useStoreInitialState } from "../../utils/saveload";
|
||||
import { EditOutlined, FilterOutlined, ShareAltOutlined } from "@ant-design/icons";
|
||||
import { DateColumn, RichColumn, SortedColumn } from "../../components/column";
|
||||
import { useLiveify } from "../../components/liveify";
|
||||
|
||||
@@ -110,6 +110,20 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
|
||||
{t("buttons.hideColumns")}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Button type="primary" icon={<ShareAltOutlined />} onClick={() => {
|
||||
let url = shareSavedState("vendorList-v2");
|
||||
try {
|
||||
if (navigator.canShare()) {
|
||||
navigator.share({ url: url });
|
||||
} else {
|
||||
window.location.hash = url.split("#")[1]
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}}>
|
||||
{t("buttons.share")}
|
||||
</Button>
|
||||
{defaultButtons}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -16,15 +16,16 @@ export interface TableState {
|
||||
|
||||
export function useInitialTableState(tableId: string): TableState {
|
||||
const [initialState] = React.useState(() => {
|
||||
const savedSorters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-sorters`) : null;
|
||||
const savedFilters = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-filters`) : null;
|
||||
const savedPagination = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-pagination`) : null;
|
||||
const savedShowColumns = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-showColumns`) : null;
|
||||
const savedSorters = hasHashProperty(`${tableId}-sorters`) ? getHashProperty(`${tableId}-sorters`) : isLocalStorageAvailable ? localStorage.getItem(`${tableId}-sorters`) : null;
|
||||
const savedFilters = hasHashProperty(`${tableId}-filters`) ? getHashProperty(`${tableId}-filters`) : isLocalStorageAvailable ? localStorage.getItem(`${tableId}-filters`) : null;
|
||||
const savedPagination = hasHashProperty(`${tableId}-pagination`) ? getHashProperty(`${tableId}-pagination`) : isLocalStorageAvailable ? localStorage.getItem(`${tableId}-pagination`) : null;
|
||||
const savedShowColumns = hasHashProperty(`${tableId}-showColumns`) ? getHashProperty(`${tableId}-showColumns`) : isLocalStorageAvailable ? localStorage.getItem(`${tableId}-showColumns`) : null;
|
||||
|
||||
const sorters = savedSorters ? JSON.parse(savedSorters) : [{ field: "id", order: "asc" }];
|
||||
const filters = savedFilters ? JSON.parse(savedFilters) : [];
|
||||
const pagination = savedPagination ? JSON.parse(savedPagination) : { page: 1, pageSize: 20 };
|
||||
const showColumns = savedShowColumns ? JSON.parse(savedShowColumns) : undefined;
|
||||
window.location.hash = "";
|
||||
return { sorters, filters, pagination, showColumns };
|
||||
});
|
||||
return initialState;
|
||||
@@ -74,3 +75,25 @@ export function useSavedState<T>(id: string, defaultValue: T) {
|
||||
|
||||
return [state, setState] as const;
|
||||
}
|
||||
|
||||
export function shareSavedState(tableId: string): string {
|
||||
const tableStates = ['sorters', 'filters', 'pagination', 'showColumns'];
|
||||
const params = new URLSearchParams();
|
||||
tableStates.forEach(s => {
|
||||
let l = localStorage.getItem(`${tableId}-${s}`);
|
||||
if (l) {
|
||||
params.append(`${tableId}-${s}`, l);
|
||||
}
|
||||
})
|
||||
return `${window.location.origin}${window.location.pathname}#${params.toString()}`
|
||||
}
|
||||
|
||||
function getHashProperty(Id: string) {
|
||||
const hash = new URLSearchParams(window.location.hash.substring(1));
|
||||
return hash.get(Id);
|
||||
}
|
||||
|
||||
function hasHashProperty(property: string): boolean {
|
||||
const hash = new URLSearchParams(window.location.hash.substring(1));
|
||||
return hash.has(property);
|
||||
}
|
||||
Reference in New Issue
Block a user